diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 0a3eff0e43..88c5cabd28 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 4b8eec3a43..e49c54e756 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index 54335ca5e4..02bc0399b1 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d6e4f4eb..963e05d7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Pokeemerald-Expansion Changelogs ## 1.10.x +- **[Version 1.10.1](docs/changelogs/1.10.x/1.10.1.md) - 🧹 Bugfix Release** - **[Version 1.10.0](docs/changelogs/1.10.x/1.10.0.md) - ✨ Feature Release** ## 1.9.x diff --git a/INSTALL.md b/INSTALL.md index 25e6adb428..6e52559f67 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -110,9 +110,9 @@ To compile the `modern` target with this toolchain, the subdirectories `lib`, `i ### Building with debug info -To build **pokeemerald.elf** with debug symbols under a modern toolchain: +To build **pokeemerald.elf** with debug symbols and debug-compatible optimization under a modern toolchain: ```bash -make DINFO=1 +make debug ``` # Useful additional tools diff --git a/Makefile b/Makefile index 71d2a48af9..e7af566de4 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ CPPFLAGS := $(INCLUDE_CPP_ARGS) -Wno-trigraphs -DMODERN=1 -DTESTING=$(TEST) ARMCC := $(PREFIX)gcc PATH_ARMCC := PATH="$(PATH)" $(ARMCC) CC1 := $(shell $(PATH_ARMCC) --print-prog-name=cc1) -quiet -override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init +override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init ifeq ($(ANALYZE),1) override CFLAGS += -fanalyzer endif @@ -346,10 +346,13 @@ endif $(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast $(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member +$(C_BUILDDIR)/agb_flash.o: override CFLAGS += -fno-toplevel-reorder $(C_BUILDDIR)/pokedex_plus_hgss.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init # Annoyingly we can't turn this on just for src/data/trainers.h $(C_BUILDDIR)/data.o: CFLAGS += -fno-show-column -fno-diagnostics-show-caret +$(TEST_BUILDDIR)/%.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init + # Dependency rules (for the *.c & *.s sources to .o files) # Have to be explicit or else missing files won't be reported. diff --git a/README.md b/README.md index 277dae2be7..70317fac5c 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,58 @@ # pokeemerald-expansion -### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there. +pokeemerald-expansion is ***a romhack base*** based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. ***It is NOT a playable romhack,*** but it has multiple features available to romhackers so that they can create their own games, so it's not meant to be played on its own. -## What is pokeemerald-expansion? - -pokeemerald-expansion is a decomp hack base project based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. It's recommended that any new projects that plan on using it, to clone this repository instead of pret's vanilla repository, as we regurlarly incorporate pret's documentation changes. This is ***NOT*** a standalone romhack, and as such, most features will be unavailable and/or unbalanced if played as is. +## Should I use this or vanilla pokeemerald for my hack? +The main advantage of using vanilla pokeemerald as a base is being able to link with other official GBA Pokémon games for battles and trading, pokeemerald-expansion can battle and trade with itself out of the box. If you don't mind losing full vanilla compatiblitity, we recommend using pokeemerald-expansion. Otherwise, use pret's pokeemerald. You'll still receive documentation improvements from pret, as we regurlarly incorporate pret's documentation changes. ## Using pokeemerald-expansion If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect. You can phrase it as the following: ``` -Based off RHH's pokeemerald-expansion 1.10.0 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.10.1 https://github.com/rh-hideout/pokeemerald-expansion/ ``` +#### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there. + Please follow the instructions in `INSTALL.md` to get pokeemerald-expansion set up on your machine. +### If I already have a project based on regular pokeemerald, can I use pokeemerald-expansion? +Yes! Keep in mind that we keep up with pret's documentation of pokeemerald, which means that if your project a bit old, you might get merge conflicts that you need to solve manually. +- 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 master`. + +With this, you'll get the latest version of pokeemerald-expansion, plus a couple of bugfixes that haven't yet been released into the next patch version :) + +## Documentation +[Please click here to visit our documentation page.](https://rh-hideout.github.io/pokeemerald-expansion/) + +## **How do I update my version of pokeemerald-expansion?** +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Check your current version. + - You can check in the debug menu's `Utilities -> Expansion Version` option. + - If the option is not available, you possibly have version 1.6.2 or older. In that case, please check the [changelogs](docs/CHANGELOG.md) to determine your version based on the features available on your repository. +- ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on. Check the [online documentation site](https://rh-hideout.github.io/pokeemerald-expansion/CHANGELOG.html) to see the latest versions of each step.) +- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.9.3, use `git pull RHH expansion/1.9.3`). + - ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on) +- Alternatively, you can update to unreleased versions of the expansion. + - ***master (stable):*** It contains unreleased **bugfixes** that will come in the next patch version. To merge, use `git pull RHH master`. + - ***upcoming (unstable, with potential bugs):*** It contains unreleased **features** that will come in the next minor version. To merge, use `git pull RHH upcoming`. + +### Please consider crediting the entire [list of contributors](https://github.com/rh-hideout/pokeemerald-expansion/wiki/Credits) in your project, as they have all worked hard to develop this project :) + +## Who maintains the project? +The project was originally started by DizzyEgg alongside other contributors. Now it is maintained by a team in the ROM Hacking Hideout's community called the "Expansion Senate". ROM Hacking Hideout (RHH for short) is a Discord-based ROM hacking community specialized in Pokémon romhacks. A lot of the discussion in regards of the development of the project happens there. + +[Click here to join the RHH Discord Server!](https://discord.gg/6CzjAG6GZk) + +## There's a bug in the project. How do I let you guys know? +Please submit any issues with the project [here](https://github.com/rh-hideout/pokeemerald-expansion/issues) and make sure that the issue wasn't reported by someone else by searching using the filters. You may also join the Discord server to try getting more in-depth support from the team and other members of the server. + +## Can I contribute even if I'm not a member of ROM Hacking Hideout? +Yes! Contributions are welcome via Pull Requests and they will be reviewed by maintainers in due time. +Also, *please follow the Pull Request template and feel free to discuss how the reviews are being handled. **Communication is key!*** Don't feel discouraged if we take a bit to review your PR, we'll get to it. + ## What features are included? - ***IMPORTANT*❗❗ Read through these to learn what features you can toggle**: - [Battle configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h) @@ -160,46 +197,4 @@ Please follow the instructions in `INSTALL.md` to get pokeemerald-expansion set - All bugfixes from pret included. - Fixed overworld snow effect. -There are some mechanics, moves and abilities that are missing and being developed. Check [the project's milestones](https://github.com/rh-hideout/pokeemerald-expansion/milestones) to see which ones. - - -### [Documentation on features can be found here](https://github.com/rh-hideout/pokeemerald-expansion/wiki) - -## If I already have a project based on regular pokeemerald, can I use pokeemerald-expansion? -Yes! Keep in mind that we keep up with pret's documentation of pokeemerald, which means that if your project a bit old, you might get merge conflicts that you need to solve manually. -- 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 master`. - -With this, you'll get the latest version of pokeemerald-expansion, plus a couple of bugfixes that haven't been released into the next patch version :) - -## **How do I update my version of pokeemerald-expansion?** -- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. -- Check your current version. - - You can check in the debug menu's `Utilities -> Expansion Version` option. - - If the option is not available, you possibly have version 1.6.2 or older. In that case, please check the [changelogs](CHANGELOG.md) to determine your version based on the features available on your repository. -- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.10.0, use `git pull RHH expansion/1.10.0`). - - ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on) -- Alternatively, you can update to unreleased versions of the expansion. - - ***master (stable):*** It contains unreleased **bugfixes** that will come in the next patch version. To merge, use `git pull RHH master`. - - ***upcoming (unstable, with potential bugs):*** It contains unreleased **features** that will come in the next minor version. To merge, use `git pull RHH upcoming`. - -### Please consider crediting the entire [list of contributors](https://github.com/rh-hideout/pokeemerald-expansion/wiki/Credits) in your project, as they have all worked hard to develop this project :) - -## There's a bug in the project. How do I let you guys know? -Please submit any issues with the project [here](https://github.com/rh-hideout/pokeemerald-expansion/issues). Make sure that the issue wasn't reported by someone else by searching using the filters. - -## Can I contribute even if I'm not a member of ROM Hacking Hideout? - -Yes! Contributions are welcome via Pull Requests and they will be reviewed by maintainers. Don't feel discouraged if we take a bit to review your PR, we'll get to it. - -## Who maintains the project? - -The project was originally started by DizzyEgg alongside other contributors. - -The project has now gotten larger and DizzyEgg is now maintaining the project as part of the ROM Hacking Hideout community. Some members of this community are taking on larger roles to help maintain the project. - -## What is the ROM Hacking Hideout? - -A Discord-based ROM hacking community that has many members who hack using the disassembly and decompilation projects for Pokémon. Quite a few contributors to the original feature branches by DizzyEgg were members of ROM Hacking Hideout. You can call it RHH for short! - -[Click here to join the RHH Discord Server!](https://discord.gg/6CzjAG6GZk) +There are some mechanics, moves and abilities that are missing and being developed. Check [the project's milestones](https://github.com/rh-hideout/pokeemerald-expansion/milestones) and our [issues page](https://github.com/rh-hideout/pokeemerald-expansion/issues) to see which ones. diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 118aebab8f..80e9b36789 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1426,11 +1426,6 @@ callnative BS_TryRevertWeatherForm .endm - .macro applysaltcure battler:req - callnative BS_ApplySaltCure - .byte \battler - .endm - .macro trysetoctolock battler:req, failInstr:req callnative BS_TrySetOctolock .byte \battler @@ -1525,8 +1520,8 @@ .4byte \jumpInstr .endm - .macro jumpifargument argument:req, jumpInstr:req - callnative BS_JumpIfArgument + .macro jumpifmovepropertyargument argument:req, jumpInstr:req + callnative BS_JumpIfMovePropertyArgument .byte \argument .4byte \jumpInstr .endm @@ -2242,11 +2237,6 @@ .4byte \jumpInstr .endm - .macro eeriespellppreduce failInstr:req - various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE - .4byte \failInstr - .endm - .macro jumpifteamhealthy battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY .4byte \jumpInstr diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index e2b76524a8..5812084ebe 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -350,34 +350,27 @@ gBattleAnimMove_MetalBurst:: waitforvisualfinish end +@Credits: Skeli gBattleAnimMove_UTurn:: - loadspritegfx ANIM_TAG_ROUND_SHADOW + loadspritegfx ANIM_TAG_SMALL_BUBBLES + loadspritegfx ANIM_TAG_RAZOR_LEAF loadspritegfx ANIM_TAG_IMPACT monbg ANIM_DEF_PARTNER - setalpha 12, 8 - playsewithpan SE_M_FLY, SOUND_PAN_ATTACKER - createsprite gFlyBallUpSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336 - playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER - createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER - jumpretfalse UTurnVisible - createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, TRUE -UTurnContinue: - delay 20 - createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1, 0 - createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1 - playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET - waitforvisualfinish - clearmonbg ANIM_DEF_PARTNER - createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER - jumpretfalse UTurnLast + splitbgprio ANIM_TARGET + setalpha 8, 8 invisible ANIM_ATTACKER -UTurnLast: - blendoff + playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER + createsprite gUTurnBallSpriteTemplate, ANIM_TARGET, 2, 0, 0, 21 waitforvisualfinish + playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 1, 2 + createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1 + createsprite gUTurnBallBackSpriteTemplate, ANIM_ATTACKER, 3, 4, 0, -16, 36 + waitforvisualfinish + visible ANIM_ATTACKER + clearmonbg ANIM_TARGET + blendoff end -UTurnVisible: - createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, FALSE - goto UTurnContinue gBattleAnimMove_CloseCombat:: loadspritegfx ANIM_TAG_IMPACT diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index f8a8747752..6d6dfe7b9c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -404,16 +404,10 @@ BattleScript_EffectHit_Pledge:: tryfaintmon BS_TARGET return -BattleScript_EffectSaltCure:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - jumpiffainted BS_TARGET, TRUE, BattleScript_EffectSaltCure_End - jumpifsubstituteblocks BattleScript_EffectSaltCure_End - applysaltcure BS_TARGET +BattleScript_MoveEffectSaltCure:: printstring STRINGID_TARGETISBEINGSALTCURED waitmessage B_WAIT_TIME_LONG -BattleScript_EffectSaltCure_End: - goto BattleScript_MoveEnd + return BattleScript_SaltCureExtraDamage:: playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL @@ -421,13 +415,13 @@ BattleScript_SaltCureExtraDamage:: call BattleScript_HurtTarget_NoString printstring STRINGID_TARGETISHURTBYSALTCURE waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET end2 BattleScript_HurtTarget_NoString: orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE healthbarupdate BS_TARGET datahpupdate BS_TARGET - tryfaintmon BS_TARGET return BattleScript_EffectCorrosiveGas:: @@ -957,13 +951,10 @@ BattleScript_HyperspaceFuryRemoveProtect:: waitmessage B_WAIT_TIME_LONG return -BattleScript_EffectPlasmaFists:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - orword gFieldStatuses, STATUS_FIELD_ION_DELUGE +BattleScript_MoveEffectIonDeluge:: printstring STRINGID_IONDELUGEON waitmessage B_WAIT_TIME_LONG - goto BattleScript_MoveEnd + return BattleScript_EffectSparklySwirl:: call BattleScript_EffectHit_Ret @@ -974,41 +965,25 @@ BattleScript_EffectSparklySwirl:: waitstate goto BattleScript_MoveEnd -BattleScript_EffectFreezyFrost:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - normalisebuffs +BattleScript_MoveEffectHaze:: printstring STRINGID_STATCHANGESGONE waitmessage B_WAIT_TIME_LONG - goto BattleScript_MoveEnd + return -BattleScript_EffectSappySeed:: - jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - jumpifhasnohp BS_TARGET, BattleScript_MoveEnd - setseeded - printfromtable gLeechSeedStringIds +BattleScript_MoveEffectLeechSeed:: + printstring STRINGID_PKMNSEEDED waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd -BattleScript_EffectBaddyBad:: - jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - setreflect +BattleScript_MoveEffectReflect:: printfromtable gReflectLightScreenSafeguardStringIds waitmessage B_WAIT_TIME_LONG - goto BattleScript_MoveEnd + return -BattleScript_EffectGlitzyGlow:: - jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - setlightscreen +BattleScript_MoveEffectLightScreen:: printfromtable gReflectLightScreenSafeguardStringIds waitmessage B_WAIT_TIME_LONG - goto BattleScript_MoveEnd + return BattleScript_EffectStuffCheeks:: attackcanceler @@ -4087,13 +4062,10 @@ BattleScript_EffectDestinyBond:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd -BattleScript_EffectEerieSpell:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - eeriespellppreduce BattleScript_MoveEnd +BattleScript_MoveEffectEerieSpell:: printstring STRINGID_PKMNREDUCEDPP waitmessage B_WAIT_TIME_LONG - goto BattleScript_MoveEnd + return BattleScript_EffectSpite:: attackcanceler @@ -5927,8 +5899,7 @@ BattleScript_OverworldStatusStarts:: BattleScript_OverworldStatusStarts_TryActivations: jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TRICK_ROOM, BattleScript_TryRoomServiceLoop - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_PLAYER, BattleScript_TryTailwindAbilitiesLoop - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_OPPONENT, BattleScript_TryTailwindAbilitiesLoop + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND, BattleScript_TryTailwindAbilitiesLoop return BattleScript_OverworldWeatherStarts:: @@ -6747,7 +6718,7 @@ BattleScript_WishComesTrue:: playanimation BS_TARGET, B_ANIM_WISH_HEAL printstring STRINGID_PKMNWISHCAMETRUE waitmessage B_WAIT_TIME_LONG - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE healthbarupdate BS_TARGET datahpupdate BS_TARGET printstring STRINGID_PKMNREGAINEDHEALTH @@ -7588,13 +7559,8 @@ BattleScript_AbilityPopUp: return BattleScript_AbilityPopUpScripting: - .if B_ABILITY_POP_UP == TRUE - showabilitypopup BS_SCRIPTING - pause 40 - .endif - recordability BS_SCRIPTING - sethword sABILITY_OVERWRITE, 0 - return + copybyte gBattlerAbility, sBATTLER + goto BattleScript_AbilityPopUp BattleScript_AbilityPopUpOverwriteThenNormal: setbyte sFIXED_ABILITY_POPUP, TRUE @@ -8366,7 +8332,6 @@ BattleScript_GrassyTerrainLoopIncrement:: addbyte gBattleCommunication, 1 jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_GrassyTerrainLoop bicword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE - jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_PERMANENT, BattleScript_GrassyTerrainHealEnd BattleScript_GrassyTerrainHealEnd: return @@ -9489,7 +9454,7 @@ BattleScript_EffectHitSetRemoveTerrain:: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce - jumpifargument ARG_TRY_REMOVE_TERRAIN_FAIL, BattleScript_RemoveTerrain + jumpifmovepropertyargument ARG_TRY_REMOVE_TERRAIN_FAIL, BattleScript_RemoveTerrain critcalc damagecalc adjustdamage @@ -9639,13 +9604,6 @@ BattleScript_EjectPackActivates:: jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd goto BattleScript_EjectPackActivate_Ret -BattleScript_EjectPackMissesTiming:: - playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT - printstring STRINGID_EJECTBUTTONACTIVATE - waitmessage B_WAIT_TIME_LONG - removeitem BS_SCRIPTING - return - BattleScript_DarkTypePreventsPrankster:: attackstring ppreduce diff --git a/data/event_scripts.s b/data/event_scripts.s index 61f969c059..dd3b8f3fbb 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -1151,3 +1151,4 @@ EventScript_VsSeekerChargingDone:: .include "data/scripts/follower.inc" .include "data/text/save.inc" .include "data/text/birch_speech.inc" + .include "data/scripts/dexnav.inc" diff --git a/data/field_effect_scripts.s b/data/field_effect_scripts.s index baa0ddb503..0425252232 100644 --- a/data/field_effect_scripts.s +++ b/data/field_effect_scripts.s @@ -25,9 +25,9 @@ gFieldEffectScriptPointers:: .4byte gFieldEffectScript_JumpSmallSplash @ FLDEFF_JUMP_SMALL_SPLASH .4byte gFieldEffectScript_LongGrass @ FLDEFF_LONG_GRASS .4byte gFieldEffectScript_JumpLongGrass @ FLDEFF_JUMP_LONG_GRASS - .4byte gFieldEffectScript_UnusedGrass @ FLDEFF_UNUSED_GRASS - .4byte gFieldEffectScript_UnusedGrass2 @ FLDEFF_UNUSED_GRASS_2 - .4byte gFieldEffectScript_UnusedSand @ FLDEFF_UNUSED_SAND + .4byte gFieldEffectScript_ShakingGrass @ FLDEFF_SHAKING_GRASS + .4byte gFieldEffectScript_ShakingGrass2 @ FLDEFF_SHAKING_LONG_GRASS + .4byte gFieldEffectScript_UnusedSand @ FLDEFF_SAND_HOLE .4byte gFieldEffectScript_WaterSurfacing @ FLDEFF_WATER_SURFACING .4byte gFieldEffectScript_BerryTreeGrowthSparkle @ FLDEFF_BERRY_TREE_GROWTH_SPARKLE .4byte gFieldEffectScript_DeepSandFootprints @ FLDEFF_DEEP_SAND_FOOTPRINTS @@ -79,7 +79,8 @@ gFieldEffectScriptPointers:: .4byte gFieldEffectScript_TracksSlither @ FLDEFF_TRACKS_SLITHER .4byte gFieldEffectScript_TracksBug @ FLDEFF_TRACKS_BUG .4byte gFieldEffectScript_TracksSpot @ FLDEFF_TRACKS_SPOT - + .4byte gFieldEffectScript_CaveDust @ FLDEFF_CAVE_DUST + gFieldEffectScript_ExclamationMarkIcon1:: field_eff_callnative FldEff_ExclamationMarkIcon field_eff_end @@ -156,12 +157,12 @@ gFieldEffectScript_JumpLongGrass:: field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect1, FldEff_JumpLongGrass field_eff_end -gFieldEffectScript_UnusedGrass:: - field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect1, FldEff_UnusedGrass +gFieldEffectScript_ShakingGrass:: + field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect1, FldEff_ShakingGrass field_eff_end -gFieldEffectScript_UnusedGrass2:: - field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect1, FldEff_UnusedGrass2 +gFieldEffectScript_ShakingGrass2:: + field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect1, FldEff_ShakingGrass2 field_eff_end gFieldEffectScript_UnusedSand:: @@ -374,3 +375,7 @@ gFieldEffectScript_TracksSpot:: gFieldEffectScript_TracksSlither:: field_eff_loadfadedpal_callnative gSpritePalette_GeneralFieldEffect0, FldEff_TracksSlither field_eff_end + +gFieldEffectScript_CaveDust:: + field_eff_loadfadedpal_callnative gSpritePalette_CaveDust FldEff_CaveDust + field_eff_end diff --git a/data/scripts/dexnav.inc b/data/scripts/dexnav.inc new file mode 100644 index 0000000000..698f501936 --- /dev/null +++ b/data/scripts/dexnav.inc @@ -0,0 +1,47 @@ +EventScript_StartDexNavBattle:: + lock + playse SE_PIN + applymovement OBJ_EVENT_ID_PLAYER Common_Movement_ExclamationMark + waitmovement 0 + waitse + dowildbattle + release + end + +EventScript_NotFoundNearby:: + msgbox sText_NotFoundNearby, MSGBOX_SIGN + end + +EventScript_MovedTooFast:: + msgbox sText_TryMovingSlower, MSGBOX_SIGN + end + +EventScript_PokemonGotAway:: + msgbox sText_PokemonGotAway, MSGBOX_SIGN + end + +EventScript_LostSignal:: + msgbox sText_LostSignal, MSGBOX_SIGN + end + +EventScript_TooDark:: + msgbox sText_TooDark, MSGBOX_SIGN + end + +sText_NotFoundNearby: + .string "It couldn't be found nearby.\n" + .string "Try looking in a different area!$" + +sText_TryMovingSlower: + .string "The Pokémon got away!\n" + .string "Try moving more slowly.$" + +sText_PokemonGotAway: + .string "The Pokémon got away!$" + +sText_LostSignal: + .string "There is no reaction.\n" + .string "The signal was lost!$" + +sText_TooDark: + .string "It's too dark to search\nfor a Pokémon!$" diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 6ef80644e6..202cdf974b 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -21,6 +21,7 @@ - [Day/Night System FAQ](tutorials/dns.md) - [Changelog](./CHANGELOG.md) - [1.10.x]() + - [Version 1.10.1](changelogs/1.10.x/1.10.1.md) - [Version 1.10.0](changelogs/1.10.x/1.10.0.md) - [1.9.x]() - [Version 1.9.4](changelogs/1.9.x/1.9.4.md) diff --git a/docs/changelogs/1.10.x/1.10.1.md b/docs/changelogs/1.10.x/1.10.1.md new file mode 100644 index 0000000000..4eb4ea8e0d --- /dev/null +++ b/docs/changelogs/1.10.x/1.10.1.md @@ -0,0 +1,140 @@ +# Version 1.10.1 + +```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.10.1`. +``` + +## 🧬 General 🧬 +### Added +* Added `FONT_SHORT_NARROWER` by @AsparagusEduardo (commit originally by @agsmgmaster64) in [#5101](https://github.com/rh-hideout/pokeemerald-expansion/pull/5101) + * Narrower font tweaks and font fitting fixes by @kittenchilly in [#5782](https://github.com/rh-hideout/pokeemerald-expansion/pull/5782) + +### Changed +* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829) + +### Fixed +* trainerproc: Fix showing incorrect error context by @mrgriffin in [#5769](https://github.com/rh-hideout/pokeemerald-expansion/pull/5769) +* Fixes UB in caps.c by @AlexOn1ine in [#5878](https://github.com/rh-hideout/pokeemerald-expansion/pull/5878) + +## 🗺️ Overworld 🗺️ +### Fixed +* Fix Off-by-One Error in Move Relearner by @iriv24 and @luckytyphlosion in [#5778](https://github.com/rh-hideout/pokeemerald-expansion/pull/5778) +* Fix HGSS dex sort orders working incorrectly by @ravepossum in [#5790](https://github.com/rh-hideout/pokeemerald-expansion/pull/5790) +* Egg cycle length fix by @hedara90 and @/BolaDeQueijo on discord discovered the issue. in [#5828](https://github.com/rh-hideout/pokeemerald-expansion/pull/5828) +* Fixed givemon not respecting perfect IVs for species by @AsparagusEduardo in [#5873](https://github.com/rh-hideout/pokeemerald-expansion/pull/5873) + - Also removed redundant `RemoveIVIndexFromList` function in `src/daycare.c`, so it uses `src/pokemon.c`'s instead +* Fix Script Scrollable Multichoice Arrow Positions by @ghoulslash in [#5884](https://github.com/rh-hideout/pokeemerald-expansion/pull/5884) + +## 🐉 Pokémon 🐉 +### Changed +* Updated Ogerpon, Enamorus and Sinistcha sprites by @kittenchilly in [#5793](https://github.com/rh-hideout/pokeemerald-expansion/pull/5793) +* New Enamorus-Incarnate sprite by @kittenchilly in [#5797](https://github.com/rh-hideout/pokeemerald-expansion/pull/5797) + +### Fixed +* Fixes Wormadam define for teachable learnset script by @AlexOn1ine in [#5783](https://github.com/rh-hideout/pokeemerald-expansion/pull/5783) +* Fix "PlantCloak" references by @AsparagusEduardo in [#5821](https://github.com/rh-hideout/pokeemerald-expansion/pull/5821) +* Misc pokemon sprite fixes by @Cafeei in [#5846](https://github.com/rh-hideout/pokeemerald-expansion/pull/5846) + +## ⚔️ Battle General ⚔️ +### Changed +* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829) + +### Fixed +* Fixes items preventing other switch in effects by @AlexOn1ine in [#5732](https://github.com/rh-hideout/pokeemerald-expansion/pull/5732) +* Fix Pokemon with No Guard failing OHKO Moves into Semi-Invulnerable Pokemon by @iriv24 and @Cafeei in [#5779](https://github.com/rh-hideout/pokeemerald-expansion/pull/5779) +* Fix move category and category icon when PSS is off by @ravepossum in [#5786](https://github.com/rh-hideout/pokeemerald-expansion/pull/5786) +* Added the missing config to use new terrains by @hedara90 in [#5792](https://github.com/rh-hideout/pokeemerald-expansion/pull/5792) +* Fixes Shed Tail substitute health by @AlexOn1ine in [#5826](https://github.com/rh-hideout/pokeemerald-expansion/pull/5826) +* `B_LAST_USED_BALL` and `.importance` by @AERDU in [#5834](https://github.com/rh-hideout/pokeemerald-expansion/pull/5834) + - prevents `B_LAST_USED_BALL` from removing balls with `.importance = 1` +* Fixes Quash-affected battlers having the wrong order for End Turn effects by @PhallenTree in [#5838](https://github.com/rh-hideout/pokeemerald-expansion/pull/5838) +* Fixes Cotton Down and Gulp Missile not interacting correctly with stat reduction prevention effects by @PhallenTree in [#5841](https://github.com/rh-hideout/pokeemerald-expansion/pull/5841) +* Fix Hit Escape moves giving Exp to the mon that switches in by @kittenchilly in [#5844](https://github.com/rh-hideout/pokeemerald-expansion/pull/5844) +* Fixed Wish triggering Disguise by @AsparagusEduardo in [#5860](https://github.com/rh-hideout/pokeemerald-expansion/pull/5860) +* Fixed `MOVE_EFFECT_FREEZE_OR_FROSTBITE` not being usable in battle scripts by @AsparagusEduardo in [#5859](https://github.com/rh-hideout/pokeemerald-expansion/pull/5859) +* Fixed Ally Switch breaking Illusion by @AsparagusEduardo in [#5879](https://github.com/rh-hideout/pokeemerald-expansion/pull/5879) +* Fixes gen3 Style Shadows out of place by @AlexOn1ine in [#5880](https://github.com/rh-hideout/pokeemerald-expansion/pull/5880) +* Fix Salt Cure script by @ghoulslash in [#5895](https://github.com/rh-hideout/pokeemerald-expansion/pull/5895) +* Fixes Eject Pack / Intimidate issue by @AlexOn1ine in [#5902](https://github.com/rh-hideout/pokeemerald-expansion/pull/5902) +* Adds Generational config for Magic Guard (Fix for Gen4+) by @AlexOn1ine in [#5893](https://github.com/rh-hideout/pokeemerald-expansion/pull/5893) +* Fixes Stance Change, Sleep Talk interaction by @AlexOn1ine in [#5909](https://github.com/rh-hideout/pokeemerald-expansion/pull/5909) +* Fixes Round doubling it's BP if previous Round failed by @AlexOn1ine in [#5907](https://github.com/rh-hideout/pokeemerald-expansion/pull/5907) + +## 🤹 Moves 🤹 +### Fixed +* Fixes absorb still draining HP when flinched by @AlexOn1ine in [#5814](https://github.com/rh-hideout/pokeemerald-expansion/pull/5814) +* Fixes Tidy Up by @AlexOn1ine in [#5819](https://github.com/rh-hideout/pokeemerald-expansion/pull/5819) +* Ally Switch extra battlerId tracking by @ghoulslash in [#5823](https://github.com/rh-hideout/pokeemerald-expansion/pull/5823) +* Sheer Force fix and move effect cleanup by @AlexOn1ine in [#5812](https://github.com/rh-hideout/pokeemerald-expansion/pull/5812) +* New U-turn animation to fix visibility by @AlexOn1ine in [#5910](https://github.com/rh-hideout/pokeemerald-expansion/pull/5910) + +## 🧶 Items 🧶 +### Fixed +* Prevent Key Items that open other menus from causing a crash if registered and used from the field by @iriv24 in [#5810](https://github.com/rh-hideout/pokeemerald-expansion/pull/5810) +* Fixes Clear Amulet displaying the wrong battler and Starting Status displaying the wrong message by @PhallenTree in [#5831](https://github.com/rh-hideout/pokeemerald-expansion/pull/5831) +* Fixes Room Service lowering the opposite mon in specific scenario by @AlexOn1ine in [#5827](https://github.com/rh-hideout/pokeemerald-expansion/pull/5827) + +## 🤖 Battle AI 🤖 +### Fixed +* Fixed ace switching bugs by @Pawkkie and @iriv24 for their diligent testing and debugging support in [#5922](https://github.com/rh-hideout/pokeemerald-expansion/pull/5922) + +## 🧹 Other Cleanup 🧹 +* Converted Stance Change to proper Form Change + Tests by @AsparagusEduardo in [#5749](https://github.com/rh-hideout/pokeemerald-expansion/pull/5749) +* Removed testing strings for automatic line breaks by @hedara90 in [#5757](https://github.com/rh-hideout/pokeemerald-expansion/pull/5757) +* Added NBSP and up+down arrows to all fonts by @hedara90 in [#5767](https://github.com/rh-hideout/pokeemerald-expansion/pull/5767) + - Use `~` or `{NBSP}` to insert a non-breaking space into a string. +* Palette cleanup by @hedara90 in [#5661](https://github.com/rh-hideout/pokeemerald-expansion/pull/5661) + - Resized some move anim palettes from 256 to 16 +* Replace power checks with IS_MOVE_STATUS by @Bassoonian and @AsparagusEduardo in [#5820](https://github.com/rh-hideout/pokeemerald-expansion/pull/5820) +* Changes Various defines to an Enum by @AsparagusEduardo in [#5840](https://github.com/rh-hideout/pokeemerald-expansion/pull/5840) +* Fix `IS_MOVE_STATUS` regression by @Bassoonian in [#5848](https://github.com/rh-hideout/pokeemerald-expansion/pull/5848) +* Remove unused various by @Bassoonian in [#5851](https://github.com/rh-hideout/pokeemerald-expansion/pull/5851) +* Removed redundant call to FillPalBufferBlack in FRLG whiteout sequence by @AsparagusEduardo in [#5854](https://github.com/rh-hideout/pokeemerald-expansion/pull/5854) +* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640) +* Fix wrong value for NUM_MOVE_EFFECTS by @Bassoonian in [#5913](https://github.com/rh-hideout/pokeemerald-expansion/pull/5913) +* Renamed OW type effectiveness function for clarity by @AsparagusEduardo in [#5917](https://github.com/rh-hideout/pokeemerald-expansion/pull/5917) + - Renamed `GetTypeEffectiveness` to `GetOverworldTypeEffectiveness`. + +## 🧪 Test Runner 🧪 +### Changed +* Gravity fix + Sky Drop Test by @ghoulslash in [#5780](https://github.com/rh-hideout/pokeemerald-expansion/pull/5780) +* Added missing Belch tests by @AsparagusEduardo in [#5881](https://github.com/rh-hideout/pokeemerald-expansion/pull/5881) +* Added missing Move Effect TODO tests - Volume D by @AsparagusEduardo in [#5887](https://github.com/rh-hideout/pokeemerald-expansion/pull/5887) +* Comment out Ally Switch Illusion test by @AsparagusEduardo in [#5901](https://github.com/rh-hideout/pokeemerald-expansion/pull/5901) +* Fixed leaking tasks not showing up in summary by @AsparagusEduardo in [#5890](https://github.com/rh-hideout/pokeemerald-expansion/pull/5890) +* Setting Battle configs during tests by @AsparagusEduardo and @SBird1337, @mrgriffin in [#5803](https://github.com/rh-hideout/pokeemerald-expansion/pull/5803) +* Speed up tests in headless mode by @AsparagusEduardo and @SBird1337 for the original fast intro code. in [#5889](https://github.com/rh-hideout/pokeemerald-expansion/pull/5889) + - This introduced the config option `B_FAST_INTRO_NO_SLIDE` which removes the sliding into for battles. +* Added missing Move Effect TODO tests - Volume E by @AsparagusEduardo in [#5915](https://github.com/rh-hideout/pokeemerald-expansion/pull/5915) + +### Fixed +* Fix test `TIMEOUT` messaging in summary by @AsparagusEduardo in [#5772](https://github.com/rh-hideout/pokeemerald-expansion/pull/5772) +* Fix octolock + defiant by @ghoulslash in [#5781](https://github.com/rh-hideout/pokeemerald-expansion/pull/5781) +* Added missing tests + Fix Coaching/Crafty Shield interaction by @AsparagusEduardo in [#5796](https://github.com/rh-hideout/pokeemerald-expansion/pull/5796) +* Fixed TODO tests not showing up when filtering by name by @AsparagusEduardo in [#5894](https://github.com/rh-hideout/pokeemerald-expansion/pull/5894) + +## 📚 Documentation 📚 +* Fixed changelog links to changelog 1.10 by @AsparagusEduardo in [#5758](https://github.com/rh-hideout/pokeemerald-expansion/pull/5758) +* Added scope document and made changes to pull request template by @pkmnsnfrn and @Pawkkie and arguably the entire senate in [#5706](https://github.com/rh-hideout/pokeemerald-expansion/pull/5706) +* Added instructions in PR template to make crediting people more clear by @pkmnsnfrn and @AsparagusEduardo made changes to my text in [#5755](https://github.com/rh-hideout/pokeemerald-expansion/pull/5755) +* Fix website not showing the "How to add mon" 1.10 tutorial by @AsparagusEduardo in [#5813](https://github.com/rh-hideout/pokeemerald-expansion/pull/5813) +* Install instructions by @hedara90 in [#5876](https://github.com/rh-hideout/pokeemerald-expansion/pull/5876) +* Change install.md to mention make debug instead of DINFO=1 by @ravepossum in [#5882](https://github.com/rh-hideout/pokeemerald-expansion/pull/5882) +* Backport changes from the wiki by @AsparagusEduardo in [#5900](https://github.com/rh-hideout/pokeemerald-expansion/pull/5900) +* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640) + +## 📦 Branch Synchronisation 📦 +### pret +* 20th of December in [#5845](https://github.com/rh-hideout/pokeemerald-expansion/pull/5845) + * Fix recorded battle link player loops by @AsparagusEduardo in [pret#2071](https://github.com/pret/pokeemerald/pull/2071) + * Added `POKEMART_LIST_END` to avoid users accidentally removing it by @AsparagusEduardo in [pret#1947](https://github.com/pret/pokeemerald/pull/1947) + * Fixed brace style inconsistencies by @AsparagusEduardo in [pret#2072](https://github.com/pret/pokeemerald/pull/2072) + * remove `sBirchSpeechPlatformBlackPal` by @DizzyEggg in [pret#2075](https://github.com/pret/pokeemerald/pull/2075) + + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.10.0...expansion/1.10.1 + + + diff --git a/docs/tutorials/how_to_new_pokemon_1_10_0.md b/docs/tutorials/how_to_new_pokemon_1_10_0.md index f6eaedee99..4d836fc7d3 100644 --- a/docs/tutorials/how_to_new_pokemon_1_10_0.md +++ b/docs/tutorials/how_to_new_pokemon_1_10_0.md @@ -858,6 +858,24 @@ static const u16 sPecharuntTeachableLearnset[] = { #endif ``` +_NOTE: At the top of this file, you will probably see this warning:_ +``` +// +// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py` +// +``` +The expansion includes a tool called the learnset helper, which aims to automate the generation of valid teachable moves. At the time of writing, this tool only supports generating TM and Tutor learnsets. However, in the future it may be expanded to deal with level up learnsets and egg moves. + +Ignore the warning shown above the first time you're adding your teachable moves (as otherwise the compiler will complain about the array not existing), but in the future (if you're using the learnset helper) simply edit what teachable moves your Pokémon can learn in one of the JSON files found in `tools/learnset_helpers/porymoves_files`. It doesn't really matter which one you add your new Pokémon to, as the tool pulls from all of the files in this folder. + +The learnset helper is useful if you plan on changing and/or increasing the available TMs and Tutor moves in your game. As an example, Bulbasaur learns Rage by TM in Red/Blue/Yellow, but in Emerald this TM does not exist. But since `tools/learnset_helpers/porymoves_files/rby.json` defines "MOVE_RAGE" as a TM move for Bulbasaur, that move would automatically be added to the `sBulbasaurTeachableLearnset` array if you were to add a Rage TM at any point. + +The learnset helper can be toggled on/off in `include/config/pokemon.h`: +``` +// Learnset helper toggles +#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors. +``` + Once more, we need to register the learnset in `gSpeciesInfo`: ```diff diff --git a/docs/tutorials/how_to_new_pokemon_1_9_0.md b/docs/tutorials/how_to_new_pokemon_1_9_0.md index e64f8e6e66..aad3332873 100644 --- a/docs/tutorials/how_to_new_pokemon_1_9_0.md +++ b/docs/tutorials/how_to_new_pokemon_1_9_0.md @@ -839,6 +839,24 @@ static const u16 sPecharuntTeachableLearnset[] = { #endif ``` +_NOTE: At the top of this file, you will probably see this warning:_ +``` +// +// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py` +// +``` +The expansion includes a tool called the learnset helper, which aims to automate the generation of valid teachable moves. At the time of writing, this tool only supports generating TM and Tutor learnsets. However, in the future it may be expanded to deal with level up learnsets and egg moves. + +Ignore the warning shown above the first time you're adding your teachable moves (as otherwise the compiler will complain about the array not existing), but in the future (if you're using the learnset helper) simply edit what teachable moves your Pokémon can learn in one of the JSON files found in `tools/learnset_helpers/porymoves_files`. It doesn't really matter which one you add your new Pokémon to, as the tool pulls from all of the files in this folder. + +The learnset helper is useful if you plan on changing and/or increasing the available TMs and Tutor moves in your game. As an example, Bulbasaur learns Rage by TM in Red/Blue/Yellow, but in Emerald this TM does not exist. But since `tools/learnset_helpers/porymoves_files/rby.json` defines "MOVE_RAGE" as a TM move for Bulbasaur, that move would automatically be added to the `sBulbasaurTeachableLearnset` array if you were to add a Rage TM at any point. + +The learnset helper can be toggled on/off in `include/config/pokemon.h`: +``` +// Learnset helper toggles +#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors. +``` + Once more, we need to register the learnset in `gSpeciesInfo`: ```diff diff --git a/docs/tutorials/how_to_testing_system.md b/docs/tutorials/how_to_testing_system.md index c573dfbbf7..da11944e25 100644 --- a/docs/tutorials/how_to_testing_system.md +++ b/docs/tutorials/how_to_testing_system.md @@ -32,7 +32,7 @@ This can be translated to an automated test as follows: ``` ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE); + ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE); } SINGLE_BATTLE_TEST("Stun Spore inflicts paralysis") @@ -78,7 +78,7 @@ This can again be translated as follows: SINGLE_BATTLE_TEST("Stun Spore does not affect Grass-types") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); PLAYER(SPECIES_ODDISH); // 1. OPPONENT(SPECIES_ODDISH); // 2. @@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Meditate raises Attack", s16 damage) PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -146,7 +146,7 @@ The overworld is not available, so it is only possible to test commands which do ### `ASSUME` `ASSUME(cond)` Causes the test to be skipped if `cond` is false. Used to document any prerequisites of the test, e.g. to test Burn reducing the Attack of a Pokémon we can observe the damage of a physical attack with and without the burn. To document that this test assumes the attack is physical we can use: -`ASSUME(gMovesInfo[MOVE_WHATEVER].category == DAMAGE_CATEGORY_PHYSICAL);` +`ASSUME(GetMoveCategory(MOVE_WHATEVER) == DAMAGE_CATEGORY_PHYSICAL);` ### `ASSUMPTIONS` ``` @@ -159,7 +159,7 @@ Should be placed immediately after any `#includes` and contain any `ASSUME` stat ``` ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_POISON_STING].effect == EFFECT_POISON_HIT); + ASSUME(GetMoveEffect(MOVE_POISON_STING) == EFFECT_POISON_HIT); } ``` @@ -201,7 +201,7 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage) PARAMETRIZE { hp = 99; } PARAMETRIZE { hp = 33; } GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -233,7 +233,7 @@ SINGLE_BATTLE_TEST("Paralysis has a 25% chance of skipping the turn") All `BattleRandom` calls involving tag will return the same number, so this cannot be used to have two moves independently hit or miss, for example. If the tag is not provided, runs the test 50 times and computes an approximate pass ratio. -`PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100);` +`PASSES_RANDOMLY(GetMoveAccuracy(move), 100);` Note that this mode of PASSES_RANDOMLY makes the tests run very slowly and should be avoided where possible. If the mechanic you are testing is missing its tag, you should add it. ### `GIVEN` diff --git a/graphics/dexnav/captured_all.png b/graphics/dexnav/captured_all.png new file mode 100644 index 0000000000..2ed8b40ca9 Binary files /dev/null and b/graphics/dexnav/captured_all.png differ diff --git a/graphics/dexnav/cursor.png b/graphics/dexnav/cursor.png new file mode 100644 index 0000000000..0b64cf95b8 Binary files /dev/null and b/graphics/dexnav/cursor.png differ diff --git a/graphics/dexnav/gui.pal b/graphics/dexnav/gui.pal new file mode 100644 index 0000000000..77939a5aba --- /dev/null +++ b/graphics/dexnav/gui.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +255 255 255 +217 73 73 +4 4 4 +1 81 113 +1 121 193 +119 177 75 +93 97 101 +91 179 211 +153 32 32 +111 141 81 +173 173 173 +187 217 167 +75 147 189 +177 219 235 +105 22 22 diff --git a/graphics/dexnav/gui_tilemap.bin b/graphics/dexnav/gui_tilemap.bin new file mode 100644 index 0000000000..0f62abbef9 Binary files /dev/null and b/graphics/dexnav/gui_tilemap.bin differ diff --git a/graphics/dexnav/gui_tiles.png b/graphics/dexnav/gui_tiles.png new file mode 100644 index 0000000000..4e3327b8ee Binary files /dev/null and b/graphics/dexnav/gui_tiles.png differ diff --git a/graphics/dexnav/hidden.png b/graphics/dexnav/hidden.png new file mode 100644 index 0000000000..2ad2e22e08 Binary files /dev/null and b/graphics/dexnav/hidden.png differ diff --git a/graphics/dexnav/hidden_search.png b/graphics/dexnav/hidden_search.png new file mode 100644 index 0000000000..d462ddef93 Binary files /dev/null and b/graphics/dexnav/hidden_search.png differ diff --git a/graphics/dexnav/no_data.png b/graphics/dexnav/no_data.png new file mode 100644 index 0000000000..a26515b5b1 Binary files /dev/null and b/graphics/dexnav/no_data.png differ diff --git a/graphics/dexnav/owned_icon.png b/graphics/dexnav/owned_icon.png new file mode 100644 index 0000000000..fdc5ef7113 Binary files /dev/null and b/graphics/dexnav/owned_icon.png differ diff --git a/graphics/dexnav/star.png b/graphics/dexnav/star.png new file mode 100644 index 0000000000..5d4b034a45 Binary files /dev/null and b/graphics/dexnav/star.png differ diff --git a/graphics/dexnav/vision.png b/graphics/dexnav/vision.png new file mode 100644 index 0000000000..74b6a14eed Binary files /dev/null and b/graphics/dexnav/vision.png differ diff --git a/graphics/field_effects/palettes/cave_dust.pal b/graphics/field_effects/palettes/cave_dust.pal new file mode 100644 index 0000000000..ed31236c4e --- /dev/null +++ b/graphics/field_effects/palettes/cave_dust.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +255 1 255 +159 122 85 +207 189 157 +199 181 149 +114 88 61 +132 101 70 +199 173 141 +225 209 193 +189 165 133 +181 149 115 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 diff --git a/graphics/field_effects/pics/cave_dust.png b/graphics/field_effects/pics/cave_dust.png new file mode 100644 index 0000000000..1f477c7803 Binary files /dev/null and b/graphics/field_effects/pics/cave_dust.png differ diff --git a/graphics/pokemon/ariados/anim_front.png b/graphics/pokemon/ariados/anim_front.png index 945c4d188f..82d947054b 100644 Binary files a/graphics/pokemon/ariados/anim_front.png and b/graphics/pokemon/ariados/anim_front.png differ diff --git a/graphics/pokemon/diggersby/anim_front.png b/graphics/pokemon/diggersby/anim_front.png index f2a0998e88..69c49c5276 100644 Binary files a/graphics/pokemon/diggersby/anim_front.png and b/graphics/pokemon/diggersby/anim_front.png differ diff --git a/graphics/pokemon/diggersby/back.png b/graphics/pokemon/diggersby/back.png index 36a4373816..a1cc29260d 100644 Binary files a/graphics/pokemon/diggersby/back.png and b/graphics/pokemon/diggersby/back.png differ diff --git a/graphics/pokemon/diggersby/shiny.pal b/graphics/pokemon/diggersby/shiny.pal index 5fd7727a42..f5f12f2cf0 100644 --- a/graphics/pokemon/diggersby/shiny.pal +++ b/graphics/pokemon/diggersby/shiny.pal @@ -6,7 +6,7 @@ JASC-PAL 120 120 112 160 160 144 8 8 8 -120 120 112 +84 84 78 48 48 56 232 232 232 240 152 168 diff --git a/graphics/pokemon/duraludon/overworld.png b/graphics/pokemon/duraludon/overworld.png index 0c8228abcb..a7488c4960 100644 Binary files a/graphics/pokemon/duraludon/overworld.png and b/graphics/pokemon/duraludon/overworld.png differ diff --git a/graphics/pokemon/honedge/anim_front.png b/graphics/pokemon/honedge/anim_front.png index 9a5dc75078..6376e2d1e2 100644 Binary files a/graphics/pokemon/honedge/anim_front.png and b/graphics/pokemon/honedge/anim_front.png differ diff --git a/graphics/pokemon/honedge/back.png b/graphics/pokemon/honedge/back.png index d9092fa13a..b1bc8634b0 100644 Binary files a/graphics/pokemon/honedge/back.png and b/graphics/pokemon/honedge/back.png differ diff --git a/graphics/pokemon/honedge/normal.pal b/graphics/pokemon/honedge/normal.pal index 51f60119df..d6a8a50995 100644 --- a/graphics/pokemon/honedge/normal.pal +++ b/graphics/pokemon/honedge/normal.pal @@ -3,17 +3,17 @@ JASC-PAL 16 152 208 160 8 48 56 -0 128 160 +36 103 149 16 16 16 80 64 40 -248 208 128 -176 152 88 +255 215 132 +181 158 90 136 104 56 -152 232 248 +102 225 253 96 192 216 80 88 88 168 168 168 216 216 216 -48 56 40 -152 128 80 -136 88 56 +99 84 80 +201 185 131 +167 139 110 diff --git a/graphics/pokemon/maractus/back.png b/graphics/pokemon/maractus/back.png index bc83adca5c..66a6520840 100644 Binary files a/graphics/pokemon/maractus/back.png and b/graphics/pokemon/maractus/back.png differ diff --git a/graphics/pokemon/pichu/spiky_eared/front.png b/graphics/pokemon/pichu/spiky_eared/front.png deleted file mode 100644 index 15b9201a27..0000000000 Binary files a/graphics/pokemon/pichu/spiky_eared/front.png and /dev/null differ diff --git a/graphics/pokemon/pichu/spiky_eared/overworld.png b/graphics/pokemon/pichu/spiky_eared/overworld.png index 7208db5108..36c1040003 100644 Binary files a/graphics/pokemon/pichu/spiky_eared/overworld.png and b/graphics/pokemon/pichu/spiky_eared/overworld.png differ diff --git a/graphics/pokemon/pincurchin/anim_front.png b/graphics/pokemon/pincurchin/anim_front.png index b8ed4964e4..ffc6bb6008 100644 Binary files a/graphics/pokemon/pincurchin/anim_front.png and b/graphics/pokemon/pincurchin/anim_front.png differ diff --git a/graphics/text_window/dexnav_pal.pal b/graphics/text_window/dexnav_pal.pal new file mode 100644 index 0000000000..cb6acc371d --- /dev/null +++ b/graphics/text_window/dexnav_pal.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 6 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +46 46 46 +0 0 0 +255 255 255 diff --git a/include/battle.h b/include/battle.h index 0f798ea481..b38c5115db 100644 --- a/include/battle.h +++ b/include/battle.h @@ -17,6 +17,7 @@ #include "battle_dynamax.h" #include "battle_terastal.h" #include "battle_gimmick.h" +#include "move.h" #include "random.h" // for rng_value_t // Helper for accessing command arguments and advancing gBattlescriptCurrInstr. @@ -70,20 +71,6 @@ // Special indicator value for shellBellDmg in SpecialStatus #define IGNORE_SHELL_BELL 0xFFFF -// For defining EFFECT_HIT etc. with battle TV scores and flags etc. -struct __attribute__((packed, aligned(2))) BattleMoveEffect -{ - const u8 *battleScript; - u16 battleTvScore:3; - u16 encourageEncore:1; - u16 twoTurnEffect:1; - u16 semiInvulnerableEffect:1; - u16 usesProtectCounter:1; - u16 padding:9; -}; - -#define GET_MOVE_BATTLESCRIPT(move) gBattleMoveEffects[gMovesInfo[move].effect].battleScript - struct ResourceFlags { u32 flags[MAX_BATTLERS_COUNT]; @@ -864,11 +851,25 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER #define F_DYNAMIC_TYPE_IGNORE_PHYSICALITY (1 << 6) // If set, the dynamic type's physicality won't be used for certain move effects. #define F_DYNAMIC_TYPE_SET (1 << 7) // Set for all dynamic types to distinguish a dynamic type of Normal (0) from no dynamic type. -#define IS_MOVE_PHYSICAL(move) (GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL) -#define IS_MOVE_SPECIAL(move) (GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL) -#define IS_MOVE_STATUS(move) (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS) +static inline bool32 IsBattleMovePhysical(u32 move) +{ + return GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL; +} -#define IS_MOVE_RECOIL(move)(gMovesInfo[move].recoil > 0 || gMovesInfo[move].effect == EFFECT_RECOIL_IF_MISS) +static inline bool32 IsBattleMoveSpecial(u32 move) +{ + return GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL; +} + +static inline bool32 IsBattleMoveStatus(u32 move) +{ + return GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS; +} + +static inline bool32 IsBattleMoveRecoil(u32 move) +{ + return GetMoveRecoil(move) > 0 || GetMoveEffect(move) == EFFECT_RECOIL_IF_MISS; +} /* Checks if 'battlerId' is any of the types. * Passing multiple types is more efficient than calling this multiple @@ -1112,7 +1113,6 @@ extern u8 gChosenMovePos; extern u16 gCurrentMove; extern u16 gChosenMove; extern u16 gCalledMove; -extern s32 gHpDealt; extern s32 gBideDmg[MAX_BATTLERS_COUNT]; extern u16 gLastUsedItem; extern u16 gLastUsedAbility; @@ -1176,7 +1176,6 @@ extern u32 gFieldStatuses; extern struct FieldTimer gFieldTimers; extern u8 gBattlerAbility; extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT]; -extern const struct BattleMoveEffect gBattleMoveEffects[]; extern void (*gPreBattleCallback1)(void); extern void (*gBattleMainFunc)(void); diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index 729d173933..7cfc28e5d6 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -116,7 +116,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv bool32 HasMoveWithCategory(u32 battler, u32 category); bool32 HasMoveWithType(u32 battler, u32 type); bool32 HasMoveEffect(u32 battlerId, u32 moveEffect); -bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument); +bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument); bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect); bool32 HasMoveWithCriticalHitChance(u32 battlerId); bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception); diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h index 968f8d48dc..dd85b2658c 100644 --- a/include/battle_gfx_sfx_util.h +++ b/include/battle_gfx_sfx_util.h @@ -6,6 +6,7 @@ void FreeBattleSpritesData(void); u16 ChooseMoveAndTargetInBattlePalace(u32 battler); void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite); void SpriteCB_TrainerSlideIn(struct Sprite *sprite); +void SpriteCB_TrainerSpawn(struct Sprite *sprite); void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status); bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument); void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId); diff --git a/include/battle_main.h b/include/battle_main.h index 7e3206c554..e8368f82d6 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -72,7 +72,7 @@ void SwapTurnOrder(u8 id1, u8 id2); u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect); u32 GetBattlerTotalSpeedStat(u32 battler); s8 GetChosenMovePriority(u32 battlerId); -s8 GetMovePriority(u32 battlerId, u16 move); +s8 GetBattleMovePriority(u32 battlerId, u16 move); s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2, u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2); s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves); diff --git a/include/battle_scripts.h b/include/battle_scripts.h index cac3ce990f..f4d97a5f66 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -422,7 +422,6 @@ extern const u8 BattleScript_EjectButtonActivates[]; extern const u8 BattleScript_EjectPackActivate_Ret[]; extern const u8 BattleScript_EjectPackActivate_End2[]; extern const u8 BattleScript_EjectPackActivates[]; -extern const u8 BattleScript_EjectPackMissesTiming[]; extern const u8 BattleScript_MentalHerbCureRet[]; extern const u8 BattleScript_MentalHerbCureEnd2[]; extern const u8 BattleScript_TerrainPreventsEnd2[]; @@ -809,18 +808,18 @@ extern const u8 BattleScript_EffectGeomancy[]; extern const u8 BattleScript_EffectFairyLock[]; extern const u8 BattleScript_EffectAllySwitch[]; extern const u8 BattleScript_EffectRelicSong[]; -extern const u8 BattleScript_EffectEerieSpell[]; +extern const u8 BattleScript_MoveEffectEerieSpell[]; extern const u8 BattleScript_EffectJungleHealing[]; extern const u8 BattleScript_EffectCoaching[]; extern const u8 BattleScript_EffectDecorate[]; extern const u8 BattleScript_EffectRecoilHP25[]; extern const u8 BattleScript_EffectStuffCheeks[]; -extern const u8 BattleScript_EffectGlitzyGlow[]; -extern const u8 BattleScript_EffectBaddyBad[]; -extern const u8 BattleScript_EffectSappySeed[]; -extern const u8 BattleScript_EffectFreezyFrost[]; +extern const u8 BattleScript_MoveEffectLightScreen[]; +extern const u8 BattleScript_MoveEffectReflect[]; +extern const u8 BattleScript_MoveEffectLeechSeed[]; +extern const u8 BattleScript_MoveEffectHaze[]; extern const u8 BattleScript_EffectSparklySwirl[]; -extern const u8 BattleScript_EffectPlasmaFists[]; +extern const u8 BattleScript_MoveEffectIonDeluge[]; extern const u8 BattleScript_EffectHyperspaceFury[]; extern const u8 BattleScript_EffectAuraWheel[]; extern const u8 BattleScript_EffectPhotonGeyser[]; @@ -843,7 +842,7 @@ extern const u8 BattleScript_EffectRevivalBlessing[]; extern const u8 BattleScript_EffectSnow[]; extern const u8 BattleScript_EffectTakeHeart[]; extern const u8 BattleScript_EffectCorrosiveGas[]; -extern const u8 BattleScript_EffectSaltCure[]; +extern const u8 BattleScript_MoveEffectSaltCure[]; extern const u8 BattleScript_EffectChillyReception[]; extern const u8 BattleScript_EffectMaxMove[]; extern const u8 BattleScript_EffectGlaiveRush[]; diff --git a/include/battle_transition.h b/include/battle_transition.h index eba514b09f..8bc80dc642 100644 --- a/include/battle_transition.h +++ b/include/battle_transition.h @@ -11,6 +11,7 @@ void GetBg0TilesDst(u16 **tilemap, u16 **tileset); extern const struct SpritePalette gSpritePalette_Pokeball; enum { + MUGSHOT_COLOR_NONE, MUGSHOT_COLOR_PURPLE, MUGSHOT_COLOR_GREEN, MUGSHOT_COLOR_PINK, diff --git a/include/battle_util.h b/include/battle_util.h index 20a228eef6..46c491a853 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -1,6 +1,8 @@ #ifndef GUARD_BATTLE_UTIL_H #define GUARD_BATTLE_UTIL_H +#include "move.h" + #define MOVE_LIMITATION_ZEROMOVE (1 << 0) #define MOVE_LIMITATION_PP (1 << 1) #define MOVE_LIMITATION_DISABLED (1 << 2) @@ -100,33 +102,37 @@ struct TypePower enum { CANCELLER_FLAGS, + CANCELLER_STANCE_CHANGE_1, CANCELLER_SKY_DROP, + CANCELLER_RECHARGE, CANCELLER_ASLEEP, CANCELLER_FROZEN, CANCELLER_OBEDIENCE, CANCELLER_TRUANT, - CANCELLER_RECHARGE, CANCELLER_FLINCH, + CANCELLER_IN_LOVE, CANCELLER_DISABLED, - CANCELLER_GRAVITY, CANCELLER_HEAL_BLOCKED, + CANCELLER_GRAVITY, + CANCELLER_THROAT_CHOP, CANCELLER_TAUNTED, CANCELLER_IMPRISONED, CANCELLER_CONFUSED, CANCELLER_PARALYSED, - CANCELLER_IN_LOVE, CANCELLER_BIDE, CANCELLER_THAW, + CANCELLER_STANCE_CHANGE_2, + CANCELLER_WEATHER_PRIMAL, + CANCELLER_DYNAMAX_BLOCKED, CANCELLER_POWDER_MOVE, CANCELLER_POWDER_STATUS, - CANCELLER_THROAT_CHOP, + CANCELLER_PROTEAN, + CANCELLER_PSYCHIC_TERRAIN, CANCELLER_EXPLODING_DAMP, CANCELLER_MULTIHIT_MOVES, CANCELLER_Z_MOVES, CANCELLER_MULTI_TARGET_MOVES, CANCELLER_END, - CANCELLER_PSYCHIC_TERRAIN, - CANCELLER_END2, }; enum { @@ -197,9 +203,8 @@ u8 DoBattlerEndTurnEffects(void); bool32 HandleWishPerishSongOnTurnEnd(void); bool32 HandleFaintedMonActions(void); void TryClearRageAndFuryCutter(void); -u8 AtkCanceller_UnableToUseMove(u32 moveType); +u32 AtkCanceller_MoveSuccessOrder(void); void SetAtkCancellerForCalledMove(void); -u8 AtkCanceller_UnableToUseMove2(void); bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2); bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility); u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef); @@ -223,7 +228,7 @@ u32 ItemBattleEffects(enum ItemEffect, u32 battler, bool32 moveTurn); void ClearVariousBattlerFlags(u32 battler); void HandleAction_RunBattleScript(void); u32 SetRandomTarget(u32 battler); -u32 GetMoveTarget(u16 move, u8 setTarget); +u32 GetBattleMoveTarget(u16 move, u8 setTarget); u8 GetAttackerObedienceForAction(); u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating); u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating); @@ -242,7 +247,7 @@ s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fi uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities); uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef); uq4_12_t GetTypeModifier(u32 atkType, u32 defType); -uq4_12_t GetTypeEffectiveness(struct Pokemon *mon, u8 moveType); +uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType); s32 GetStealthHazardDamage(u8 hazardType, u32 battler); s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp); bool32 CanMegaEvolve(u32 battler); @@ -297,7 +302,7 @@ bool32 IsGen6ExpShareEnabled(void); bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect); bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance); bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect); -bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument); +bool32 IsMoveEffectRemoveSpeciesType(u32 move, u32 moveEffect, u32 argument); bool32 MoveHasChargeTurnAdditionalEffect(u32 move); bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef); bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef); @@ -325,12 +330,13 @@ u32 GetBattlerType(u32 battler, u32 typeIndex, bool32 ignoreTera); bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon); bool8 IsMonBannedFromSkyBattles(u16 species); void RemoveBattlerType(u32 battler, u8 type); -u32 GetMoveType(u32 move); +u32 GetBattleMoveType(u32 move); void TryActivateSleepClause(u32 battler, u32 indexInParty); void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty); bool32 IsSleepClauseActiveForSide(u32 battlerSide); bool32 IsSleepClauseEnabled(); void ClearDamageCalcResults(void); u32 DoesDestinyBondFail(u32 battler); +bool32 IsMoveEffectBlockedByTarget(u32 ability); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/config/battle.h b/include/config/battle.h index 901b611a76..117e0cc31c 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -157,6 +157,7 @@ // In Gen3, Effect Spore has a 10% chance to sleep, poison or paralyze, with an equal chance. // In Gen4, it's 30%. In Gen5+ it has 11% to sleep, 9% chance to poison and 10% chance to paralyze. #define B_PICKUP_WILD GEN_LATEST // In Gen9+, Pickup allows its user to pickup its own used item at the end of the turn in wild battles. +#define B_MAGIC_GUARD GEN_LATEST // In Gen4+, Magic Guard ignores immobilization caused by paralysis // Item settings #define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. @@ -229,7 +230,8 @@ // Interface settings #define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle. -#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. +#define B_FAST_INTRO_PKMN_TEXT TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. +#define B_FAST_INTRO_NO_SLIDE FALSE // If set to TRUE, the slide animation that happens at the beginning of the battle is skipped. #define B_FAST_HP_DRAIN TRUE // If set to TRUE, HP bars will move faster. #define B_FAST_EXP_GROW TRUE // If set to TRUE, EXP bars will move faster. #define B_SHOW_TARGETS TRUE // If set to TRUE, all available targets, for moves hitting 2 or 3 Pokémon, will be shown before selecting a move. diff --git a/include/config/dexnav.h b/include/config/dexnav.h new file mode 100644 index 0000000000..20d05f7a23 --- /dev/null +++ b/include/config/dexnav.h @@ -0,0 +1,72 @@ +#ifndef GUARD_CONFIG_DEXNAV_H +#define GUARD_CONFIG_DEXNAV_H + +#define DEXNAV_ENABLED FALSE // Whether or not DexNav is enabled. If TRUE, flags/vars below must all be non-zero +#define USE_DEXNAV_SEARCH_LEVELS FALSE /* WARNING: POSSIBLY EXCEEDS SAVEBLOCK SPACE! REQUIRES 1 BYTE PER SPECIES */ + +// Flag/var defines +#define FLAG_SYS_DEXNAV_SEARCH 0 // Searching for mon +#define FLAG_SYS_DEXNAV_GET 0 // DexNav shows in start menu +#define FLAG_SYS_DETECTOR_MODE 0 // Allow player to find hidden mons +#define VAR_DEXNAV_SPECIES 0 // Registered DexNav species +#define VAR_DEXNAV_STEP_COUNTER 0 // Steps for finding hidden pokemon + +// Search parameters +#define DEXNAV_TIMEOUT 15 // 15 seconds is the time out. Max of 1092 seconds allowed +#define SNEAKING_PROXIMITY 4 // Tile amount +#define CREEPING_PROXIMITY 2 +#define MAX_PROXIMITY 20 + +#define DEXNAV_CHAIN_MAX 100 // maximum chain value + +// hidden pokemon options - an approximation of values to due to lack of available data +#define HIDDEN_MON_STEP_COUNT 100 // Look for hidden pokemon every x steps +#define HIDDEN_MON_SEARCH_RATE 25 // x% chance of finding hidden pokemon every x steps +#define HIDDEN_MON_PROBABILTY 15 // x% chance of finding hidden mon compared to regular encounter data + +//// SEARCH PROBABILITIES +// See https://bulbapedia.bulbagarden.net/wiki/DexNav#Benefits +// Chance of encountering egg move at search levels +#define SEARCHLEVEL0_MOVECHANCE 0 +#define SEARCHLEVEL5_MOVECHANCE 21 +#define SEARCHLEVEL10_MOVECHANCE 46 +#define SEARCHLEVEL25_MOVECHANCE 58 +#define SEARCHLEVEL50_MOVECHANCE 63 +#define SEARCHLEVEL100_MOVECHANCE 83 +// Chance of encountering Hidden Abilities at search levels +#define SEARCHLEVEL0_ABILITYCHANCE 0 +#define SEARCHLEVEL5_ABILITYCHANCE 0 +#define SEARCHLEVEL10_ABILITYCHANCE 5 +#define SEARCHLEVEL25_ABILITYCHANCE 15 +#define SEARCHLEVEL50_ABILITYCHANCE 20 +#define SEARCHLEVEL100_ABILITYCHANCE 23 +// Chance of encountering held item +#define SEARCHLEVEL0_ITEM 0 +#define SEARCHLEVEL5_ITEM 0 +#define SEARCHLEVEL10_ITEM 1 +#define SEARCHLEVEL25_ITEM 7 +#define SEARCHLEVEL50_ITEM 6 +#define SEARCHLEVEL100_ITEM 12 +// Chance of encountering one star potential +#define SEARCHLEVEL0_ONESTAR 0 +#define SEARCHLEVEL5_ONESTAR 14 +#define SEARCHLEVEL10_ONESTAR 17 +#define SEARCHLEVEL25_ONESTAR 17 +#define SEARCHLEVEL50_ONESTAR 15 +#define SEARCHLEVEL100_ONESTAR 8 +// Chance of encountering two star potential +#define SEARCHLEVEL0_TWOSTAR 0 +#define SEARCHLEVEL5_TWOSTAR 1 +#define SEARCHLEVEL10_TWOSTAR 9 +#define SEARCHLEVEL25_TWOSTAR 16 +#define SEARCHLEVEL50_TWOSTAR 17 +#define SEARCHLEVEL100_TWOSTAR 24 +// Chance of encountering three star potential +#define SEARCHLEVEL0_THREESTAR 0 +#define SEARCHLEVEL5_THREESTAR 0 +#define SEARCHLEVEL10_THREESTAR 1 +#define SEARCHLEVEL25_THREESTAR 7 +#define SEARCHLEVEL50_THREESTAR 6 +#define SEARCHLEVEL100_THREESTAR 12 + +#endif // GUARD_CONFIG_DEXNAV_H diff --git a/include/constants/battle.h b/include/constants/battle.h index ed19a72d9c..1685b0e582 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -266,7 +266,6 @@ #define STATUS_FIELD_PSYCHIC_TERRAIN (1 << 9) #define STATUS_FIELD_ION_DELUGE (1 << 10) #define STATUS_FIELD_FAIRY_LOCK (1 << 11) -#define STATUS_FIELD_TERRAIN_PERMANENT (1 << 12) // Overworld thunderstorm generates electric terrain #define STATUS_FIELD_TERRAIN_ANY (STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN) @@ -331,7 +330,11 @@ #define MOVE_EFFECT_TOXIC 6 #define MOVE_EFFECT_FROSTBITE 7 #define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status -#define MOVE_EFFECT_FREEZE_OR_FROSTBITE (B_USE_FROSTBITE == TRUE ? MOVE_EFFECT_FROSTBITE : MOVE_EFFECT_FREEZE) +#if B_USE_FROSTBITE == TRUE +#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FROSTBITE +#else +#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FREEZE +#endif #define MOVE_EFFECT_CONFUSION 8 #define MOVE_EFFECT_FLINCH 9 #define MOVE_EFFECT_TRI_ATTACK 10 @@ -405,8 +408,16 @@ #define MOVE_EFFECT_PSYCHIC_NOISE 78 #define MOVE_EFFECT_TERA_BLAST 79 #define MOVE_EFFECT_ORDER_UP 80 +#define MOVE_EFFECT_ION_DELUGE 81 +#define MOVE_EFFECT_AROMATHERAPY 82 // No functionality yet +#define MOVE_EFFECT_HAZE 83 +#define MOVE_EFFECT_LEECH_SEED 84 +#define MOVE_EFFECT_REFLECT 85 +#define MOVE_EFFECT_LIGHT_SCREEN 86 +#define MOVE_EFFECT_SALT_CURE 87 +#define MOVE_EFFECT_EERIE_SPELL 88 -#define NUM_MOVE_EFFECTS 81 +#define NUM_MOVE_EFFECTS 89 #define MOVE_EFFECT_AFFECTS_USER 0x2000 #define MOVE_EFFECT_CERTAIN 0x4000 @@ -509,7 +520,7 @@ #define MOVE_TARGET_ALLY (1 << 7) #define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER) // No functionality for status moves -// For the second argument of GetMoveTarget, when no target override is needed +// For the second argument of GetBattleMoveTarget, when no target override is needed #define NO_TARGET_OVERRIDE 0 // Constants for Parental Bond @@ -527,15 +538,24 @@ // Constants for B_VAR_STARTING_STATUS // Timer value controlled by B_VAR_STARTING_STATUS_TIMER -#define STARTING_STATUS_NONE 0 -#define STARTING_STATUS_ELECTRIC_TERRAIN 1 -#define STARTING_STATUS_MISTY_TERRAIN 2 -#define STARTING_STATUS_GRASSY_TERRAIN 3 -#define STARTING_STATUS_PSYCHIC_TERRAIN 4 -#define STARTING_STATUS_TRICK_ROOM 5 -#define STARTING_STATUS_MAGIC_ROOM 6 -#define STARTING_STATUS_WONDER_ROOM 7 -#define STARTING_STATUS_TAILWIND_PLAYER 8 -#define STARTING_STATUS_TAILWIND_OPPONENT 9 +enum StartingStatus +{ + STARTING_STATUS_NONE, + STARTING_STATUS_ELECTRIC_TERRAIN, + STARTING_STATUS_MISTY_TERRAIN, + STARTING_STATUS_GRASSY_TERRAIN, + STARTING_STATUS_PSYCHIC_TERRAIN, + STARTING_STATUS_TRICK_ROOM, + STARTING_STATUS_MAGIC_ROOM, + STARTING_STATUS_WONDER_ROOM, + STARTING_STATUS_TAILWIND_PLAYER, + STARTING_STATUS_TAILWIND_OPPONENT, + STARTING_STATUS_RAINBOW_PLAYER, + STARTING_STATUS_RAINBOW_OPPONENT, + STARTING_STATUS_SEA_OF_FIRE_PLAYER, + STARTING_STATUS_SEA_OF_FIRE_OPPONENT, + STARTING_STATUS_SWAMP_PLAYER, + STARTING_STATUS_SWAMP_OPPONENT, +}; #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 15edbd28ef..df752bf496 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -285,7 +285,6 @@ enum { EFFECT_ALLY_SWITCH, EFFECT_RELIC_SONG, EFFECT_BODY_PRESS, - EFFECT_EERIE_SPELL, EFFECT_JUNGLE_HEALING, EFFECT_COACHING, EFFECT_LASH_OUT, @@ -296,12 +295,7 @@ enum { EFFECT_RECOIL_HP_25, EFFECT_STUFF_CHEEKS, EFFECT_GRAV_APPLE, - EFFECT_GLITZY_GLOW, - EFFECT_BADDY_BAD, - EFFECT_SAPPY_SEED, - EFFECT_FREEZY_FROST, EFFECT_SPARKLY_SWIRL, - EFFECT_PLASMA_FISTS, EFFECT_HYPERSPACE_FURY, EFFECT_AURA_WHEEL, EFFECT_PHOTON_GEYSER, @@ -334,7 +328,6 @@ enum { EFFECT_COLLISION_COURSE, EFFECT_CORROSIVE_GAS, EFFECT_POPULATION_BOMB, - EFFECT_SALT_CURE, EFFECT_CHILLY_RECEPTION, EFFECT_MAX_MOVE, EFFECT_GLAIVE_RUSH, diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 50e39b767e..bd1c61ec09 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -187,7 +187,6 @@ enum CmdVarious VARIOUS_TERRAIN_SEED, VARIOUS_MAKE_INVISIBLE, VARIOUS_ROOM_SERVICE, - VARIOUS_EERIE_SPELL_PP_REDUCE, VARIOUS_JUMP_IF_TEAM_HEALTHY, VARIOUS_TRY_HEAL_QUARTER_HP, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED, diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 5149e85bcf..463a7fdd81 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -1010,9 +1010,11 @@ #define B_MSG_SET_TRICK_ROOM 4 #define B_MSG_SET_MAGIC_ROOM 5 #define B_MSG_SET_WONDER_ROOM 6 -#define B_MSG_SET_TAILWIND_PLAYER 7 -#define B_MSG_SET_TAILWIND_OPPONENT 8 -#define B_MSG_STARTING_STATUS_COUNT 9 +#define B_MSG_SET_TAILWIND 7 +#define B_MSG_SET_RAINBOW 8 +#define B_MSG_SET_SEA_OF_FIRE 9 +#define B_MSG_SET_SWAMP 10 +#define B_MSG_STARTING_STATUS_COUNT 11 // gWrappedStringIds diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 1f2af1a226..6b3a5ace78 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -1,7 +1,7 @@ #ifndef GUARD_CONSTANTS_EXPANSION_H #define GUARD_CONSTANTS_EXPANSION_H -// Last version: 1.10.0 +// Last version: 1.10.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 11 #define EXPANSION_VERSION_PATCH 0 diff --git a/include/constants/field_effects.h b/include/constants/field_effects.h index 5df5a7f876..0543930fe7 100644 --- a/include/constants/field_effects.h +++ b/include/constants/field_effects.h @@ -20,9 +20,9 @@ #define FLDEFF_JUMP_SMALL_SPLASH 16 #define FLDEFF_LONG_GRASS 17 #define FLDEFF_JUMP_LONG_GRASS 18 -#define FLDEFF_UNUSED_GRASS 19 -#define FLDEFF_UNUSED_GRASS_2 20 -#define FLDEFF_UNUSED_SAND 21 +#define FLDEFF_SHAKING_GRASS 19 +#define FLDEFF_SHAKING_LONG_GRASS 20 +#define FLDEFF_SAND_HOLE 21 #define FLDEFF_WATER_SURFACING 22 #define FLDEFF_BERRY_TREE_GROWTH_SPARKLE 23 #define FLDEFF_DEEP_SAND_FOOTPRINTS 24 @@ -75,6 +75,7 @@ #define FLDEFF_TRACKS_SLITHER 70 #define FLDEFF_TRACKS_SPOT 71 #define FLDEFF_TRACKS_BUG 72 +#define FLDEFF_CAVE_DUST 73 #define FLDEFFOBJ_SHADOW_S 0 #define FLDEFFOBJ_SHADOW_M 1 @@ -116,6 +117,7 @@ #define FLDEFFOBJ_TRACKS_SLITHER 37 #define FLDEFFOBJ_TRACKS_SPOT 38 #define FLDEFFOBJ_TRACKS_BUG 39 +#define FLDEFFOBJ_CAVE_DUST 40 #define FLDEFF_PAL_TAG_CUT_GRASS 0x1000 #define FLDEFF_PAL_TAG_SECRET_POWER_TREE 0x1003 @@ -129,6 +131,7 @@ #define FLDEFF_PAL_TAG_SMALL_SPARKLE 0x100F #define FLDEFF_PAL_TAG_HOF_MONITOR 0x1010 #define FLDEFF_PAL_TAG_UNKNOWN 0x1011 +#define FLDEFF_PAL_TAG_CAVE_DUST 0x1012 #define FLDEFF_PAL_TAG_FIELD_MOVE_MON 0x8400 // tile tags, for field effects that may have many copies on screen at once diff --git a/include/constants/game_stat.h b/include/constants/game_stat.h index 5796afbaec..17e328d5be 100644 --- a/include/constants/game_stat.h +++ b/include/constants/game_stat.h @@ -53,8 +53,9 @@ #define GAME_STAT_ENTERED_HOT_SPRINGS 49 #define GAME_STAT_NUM_UNION_ROOM_BATTLES 50 #define GAME_STAT_PLAYED_BERRY_CRUSH 51 +#define GAME_STAT_DEXNAV_SCANNED 52 -#define NUM_USED_GAME_STATS 52 +#define NUM_USED_GAME_STATS 53 #define NUM_GAME_STATS 64 #endif // GUARD_CONSTANTS_GAME_STAT_H diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h new file mode 100644 index 0000000000..557b34b653 --- /dev/null +++ b/include/constants/generational_changes.h @@ -0,0 +1,10 @@ +#ifndef GUARD_CONSTANTS_GENERATIONAL_CHANGES_H +#define GUARD_CONSTANTS_GENERATIONAL_CHANGES_H + +enum GenConfigTag +{ + GEN_CONFIG_GALE_WINGS, + GEN_CONFIG_COUNT +}; + +#endif // GUARD_CONSTANTS_GENERATIONAL_CHANGES_H diff --git a/include/constants/global.h b/include/constants/global.h index 89508e374d..3476bd3680 100644 --- a/include/constants/global.h +++ b/include/constants/global.h @@ -8,6 +8,7 @@ #include "config/caps.h" #include "config/pokemon.h" #include "config/overworld.h" +#include "config/dexnav.h" // Invalid Versions show as "----------" in Gen 4 and Gen 5's summary screen. // In Gens 6 and 7, invalid versions instead show "a distant land" in the summary screen. diff --git a/include/constants/wild_encounter.h b/include/constants/wild_encounter.h index ae669a2c35..364d18350f 100644 --- a/include/constants/wild_encounter.h +++ b/include/constants/wild_encounter.h @@ -5,6 +5,7 @@ #define WATER_WILD_COUNT 5 #define ROCK_WILD_COUNT 5 #define FISH_WILD_COUNT 10 +#define HIDDEN_WILD_COUNT 3 #define NUM_ALTERING_CAVE_TABLES 9 diff --git a/include/data.h b/include/data.h index ef59aae569..8d90d679b3 100644 --- a/include/data.h +++ b/include/data.h @@ -88,7 +88,7 @@ struct Trainer /*0x12*/ u8 trainerPic; /*0x13*/ u8 trainerName[TRAINER_NAME_LENGTH + 1]; /*0x1E*/ bool8 doubleBattle:1; - bool8 mugshotEnabled:1; + bool8 padding:1; u8 startingStatus:6; // this trainer starts a battle with a given status. see include/constants/battle.h for values /*0x1F*/ u8 mugshotColor; /*0x20*/ u8 partySize; @@ -235,7 +235,7 @@ static inline const u8 GetTrainerPartySizeFromId(u16 trainerId) static inline const bool32 DoesTrainerHaveMugshot(u16 trainerId) { - return gTrainers[SanitizeTrainerId(trainerId)].mugshotEnabled; + return gTrainers[SanitizeTrainerId(trainerId)].mugshotColor; } static inline const u8 GetTrainerMugshotColorFromId(u16 trainerId) diff --git a/include/daycare.h b/include/daycare.h index 4d5b470f8b..a7ef5581f9 100644 --- a/include/daycare.h +++ b/include/daycare.h @@ -34,5 +34,6 @@ void ShowDaycareLevelMenu(void); void ChooseSendDaycareMon(void); u8 GetEggMovesBySpecies(u16 species, u16 *eggMoves); bool8 SpeciesCanLearnEggMove(u16 species, u16 move); +u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves); #endif // GUARD_DAYCARE_H diff --git a/include/dexnav.h b/include/dexnav.h new file mode 100644 index 0000000000..baa8f8c5a7 --- /dev/null +++ b/include/dexnav.h @@ -0,0 +1,77 @@ +#ifndef GUARD_DEXNAV_H +#define GUARD_DEXNAV_H + +#include "config/dexnav.h" + +// GUI Info +#define ROW_WATER 0 +#define ROW_LAND_TOP 1 +#define ROW_LAND_BOT 2 +#define ROW_HIDDEN 3 +#define ROWS_COUNT 4 + +#define ROW_WATER_ICON_X 30 +#define ROW_WATER_ICON_Y 35 + +#define ROW_LAND_ICON_X 20 +#define ROW_LAND_TOP_ICON_Y 72 +#define ROW_LAND_BOT_ICON_Y (ROW_LAND_TOP_ICON_Y + 28) + +#define ROW_HIDDEN_ICON_X 52 +#define ROW_HIDDEN_ICON_Y 138 + +#define ENCOUNTER_TYPE_LAND 0 +#define ENCOUNTER_TYPE_WATER 1 +#define ENCOUNTER_TYPE_HIDDEN 2 // Get from species + +#define COL_WATER_COUNT 5 +#define COL_LAND_COUNT 6 +#define COL_HIDDEN_COUNT 3 + +#define COL_WATER_MAX (COL_WATER_COUNT - 1) +#define COL_LAND_MAX (COL_LAND_COUNT - 1) +#define COL_HIDDEN_MAX (COL_HIDDEN_COUNT - 1) + +// SEARCH INFO +#define SCANSTART_X 0 +#define SCANSTART_Y 0 +#define SCANSIZE_X 12 +#define SCANSIZE_Y 12 + +#define SPECIES_INFO_Y 5 +#define TYPE_ICONS_Y (SPECIES_INFO_Y + 24) +#define SEARCH_LEVEL_Y (TYPE_ICONS_Y + 24) +#define HA_INFO_Y (SEARCH_LEVEL_Y + 24) +#define CHAIN_BONUS_Y (HA_INFO_Y + 24) + +#define MON_LEVEL_NONEXISTENT 255 // If mon not in area GetEncounterLevel returns this to exit the search + +// GUI tags +#define ICON_PAL_TAG 56000 +#define ICON_GFX_TAG 55130 +#define SELECTION_CURSOR_TAG 0x4005 +#define CAPTURED_ALL_TAG 0x4002 + +// Search tags +#define OWNED_ICON_TAG 0x4003 +#define HIDDEN_SEARCH_TAG SELECTION_CURSOR_TAG +#define HIDDEN_MON_ICON_TAG 0x4006 +#define LIT_STAR_TILE_TAG 0x4010 +#define HELD_ITEM_TAG 0xd750 + +// DexNav search variable +#define DEXNAV_MASK_SPECIES 0x3FFF // First 14 bits +#define DEXNAV_MASK_ENVIRONMENT 0xC000 // Last two bit + +void EndDexNavSearch(u8 taskId); +void Task_OpenDexNavFromStartMenu(u8 taskId); +bool8 TryStartDexNavSearch(void); +void TryIncrementSpeciesSearchLevel(u16 dexNum); +void ResetDexNavSearch(void); +bool8 TryFindHiddenPokemon(void); +u32 CalculateDexNavShinyRolls(void); +void IncrementDexNavChain(void); + +extern bool8 gDexNavBattle; + +#endif // GUARD_DEXNAV_H diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 03fac6a270..6994892578 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -320,6 +320,7 @@ u8 GetJumpMovementAction(u32); u8 GetJump2MovementAction(u32); u8 CopySprite(struct Sprite *sprite, s16 x, s16 y, u8 subpriority); u8 CreateCopySpriteAt(struct Sprite *sprite, s16 x, s16 y, u8 subpriority); +bool8 IsElevationMismatchAt(u8, s16, s16); u8 MovementType_WanderAround_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_WanderAround_Step1(struct ObjectEvent *, struct Sprite *); diff --git a/include/event_scripts.h b/include/event_scripts.h index 60a8d6123e..133d9fa98b 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -653,5 +653,13 @@ extern const u8 Common_Movement_FollowerSafeEnd[]; extern const u8 EventScript_CancelMessageBox[]; extern const u8 Common_EventScript_ShowPokemonCenterSign[]; extern const u8 Common_EventScript_ShowPokemartSign[]; +// DexNav +extern const u8 EventScript_StartDexNavBattle[]; +extern const u8 EventScript_NotFoundNearby[]; +extern const u8 EventScript_PokemonGotAway[]; +extern const u8 EventScript_LostSignal[]; +extern const u8 EventScript_TooDark[]; +extern const u8 EventScript_MovedTooFast[]; + #endif // GUARD_EVENT_SCRIPTS_H diff --git a/include/field_control_avatar.h b/include/field_control_avatar.h index da23fe4336..9a55f9e7bf 100644 --- a/include/field_control_avatar.h +++ b/include/field_control_avatar.h @@ -11,7 +11,7 @@ struct FieldInput bool8 heldDirection2:1; bool8 tookStep:1; bool8 pressedBButton:1; - bool8 input_field_1_0:1; + bool8 pressedRButton:1; bool8 input_field_1_1:1; bool8 input_field_1_2:1; bool8 input_field_1_3:1; diff --git a/include/field_effect.h b/include/field_effect.h index 93a74f1ba2..3db86bc219 100644 --- a/include/field_effect.h +++ b/include/field_effect.h @@ -48,5 +48,7 @@ void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b); void FreeResourcesAndDestroySprite(struct Sprite *sprite, u8 spriteId); u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority); void StartEscapeRopeFieldEffect(void); +void FieldEffectFreeGraphicsResources(struct Sprite *sprite); +void FieldEff_CaveDust(void); #endif // GUARD_FIELD_EFFECTS_H diff --git a/include/generational_changes.h b/include/generational_changes.h new file mode 100644 index 0000000000..5a726007c3 --- /dev/null +++ b/include/generational_changes.h @@ -0,0 +1,41 @@ +#ifndef GUARD_GENERATIONAL_CHANGES_H +#define GUARD_GENERATIONAL_CHANGES_H + +#include "constants/generational_changes.h" +#include "config/battle.h" + +static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] = +{ + [GEN_CONFIG_GALE_WINGS] = B_GALE_WINGS, +}; + +#if TESTING +extern u8 *gGenerationalChangesTestOverride; +#endif + +static inline u32 GetGenConfig(enum GenConfigTag configTag) +{ + if (configTag >= GEN_CONFIG_COUNT) return GEN_LATEST; +#if TESTING + if (gGenerationalChangesTestOverride == NULL) return sGenerationalChanges[configTag]; + return gGenerationalChangesTestOverride[configTag]; +#else + return sGenerationalChanges[configTag]; +#endif +} + +static inline void SetGenConfig(enum GenConfigTag configTag, u32 value) +{ +#if TESTING + if (configTag >= GEN_CONFIG_COUNT) return; + if (gGenerationalChangesTestOverride == NULL) return; + gGenerationalChangesTestOverride[configTag] = value; +#endif +} + +#if TESTING +void TestInitConfigData(void); +void TestFreeConfigData(void); +#endif + +#endif // GUARD_GENERATIONAL_CHANGES_H diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 9a555e4450..9c2cc4e95b 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -326,7 +326,8 @@ struct PlayerAvatar { /*0x00*/ u8 flags; /*0x01*/ u8 transitionFlags; // used to be named bike, but its definitely not that. seems to be some transition flags - /*0x02*/ u8 runningState; // this is a static running state. 00 is not moving, 01 is turn direction, 02 is moving. + /*0x02*/ u8 runningState:7; // this is a static running state. 00 is not moving, 01 is turn direction, 02 is moving. + u8 creeping:1; /*0x03*/ u8 tileTransitionState; // this is a transition running state: 00 is not moving, 01 is transition between tiles, 02 means you are on the frame in which you have centered on a tile but are about to keep moving, even if changing directions. 2 is also used for a ledge hop, since you are transitioning. /*0x04*/ u8 spriteId; /*0x05*/ u8 objectEventId; diff --git a/include/global.h b/include/global.h index dc6bf8b9cf..586bb374b8 100644 --- a/include/global.h +++ b/include/global.h @@ -211,7 +211,11 @@ struct SaveBlock3 #if OW_SHOW_ITEM_DESCRIPTIONS == OW_ITEM_DESCRIPTIONS_FIRST_TIME u8 itemFlags[ITEM_FLAGS_COUNT]; #endif -}; +#if USE_DEXNAV_SEARCH_LEVELS == TRUE + u8 dexNavSearchLevels[NUM_SPECIES]; +#endif + u8 dexNavChain; +}; /* max size 1624 bytes */ extern struct SaveBlock3 *gSaveBlock3Ptr; diff --git a/include/main.h b/include/main.h index eba04cbaa9..b64c9349a8 100644 --- a/include/main.h +++ b/include/main.h @@ -53,7 +53,6 @@ extern u16 gKeyRepeatContinueDelay; extern bool8 gSoftResetDisabled; extern IntrFunc gIntrTable[]; extern u8 gLinkVSyncDisabled; -extern u32 IntrMain_Buffer[]; extern s8 gPcmDmaCounter; void AgbMain(void); diff --git a/include/move.h b/include/move.h new file mode 100644 index 0000000000..67206d9ba2 --- /dev/null +++ b/include/move.h @@ -0,0 +1,544 @@ +#ifndef GUARD_MOVES_H +#define GUARD_MOVES_H + +#include "contest_effect.h" +#include "constants/battle_move_effects.h" +#include "constants/moves.h" + +// For defining EFFECT_HIT etc. with battle TV scores and flags etc. +struct __attribute__((packed, aligned(2))) BattleMoveEffect +{ + const u8 *battleScript; + u16 battleTvScore:3; + u16 encourageEncore:1; + u16 twoTurnEffect:1; + u16 semiInvulnerableEffect:1; + u16 usesProtectCounter:1; + u16 padding:9; +}; + +#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__} +#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ )) + +enum SheerForceBoost +{ + SHEER_FORCE_AUTO_BOOST, // This is the default state when a move has a move effect with a chance + SHEER_FORCE_BOOST, // If a move effect doesn't have an effect with a chance this can force a boost + SHEER_FORCE_NO_BOOST, // Prevents a Sheer Force boost +}; + +struct AdditionalEffect +{ + u16 moveEffect; + u8 self:1; + u8 onlyIfTargetRaisedStats:1; + u8 onChargeTurnOnly:1; + u8 sheerForceBoost:2; // Handles edge cases for Sheer Force + u8 padding:3; + u8 chance; // 0% = effect certain, primary effect +}; + +struct MoveInfo +{ + const u8 *name; + const u8 *description; + u16 effect; + u16 type:5; // Up to 32 + u16 category:2; + u16 power:9; // up to 511 + // end of word + u16 accuracy:7; + u16 target:9; + u8 pp; + union { + u8 effect; + u8 powerOverride; + } zMove; + // end of word + s32 priority:4; + u32 recoil:7; + u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit. + u32 criticalHitStage:2; + bool32 alwaysCriticalHit:1; + u32 numAdditionalEffects:2; // limited to 3 - don't want to get too crazy + // Flags + bool32 makesContact:1; + bool32 ignoresProtect:1; + bool32 magicCoatAffected:1; + bool32 snatchAffected:1; + bool32 ignoresKingsRock:1; + bool32 punchingMove:1; + bool32 bitingMove:1; + bool32 pulseMove:1; + bool32 soundMove:1; + bool32 ballisticMove:1; + bool32 powderMove:1; + bool32 danceMove:1; + // end of word + bool32 windMove:1; + bool32 slicingMove:1; + bool32 healingMove:1; + bool32 minimizeDoubleDamage:1; + bool32 ignoresTargetAbility:1; + bool32 ignoresTargetDefenseEvasionStages:1; + bool32 damagesUnderground:1; + bool32 damagesUnderwater:1; + bool32 damagesAirborne:1; + bool32 damagesAirborneDoubleDamage:1; + bool32 ignoreTypeIfFlyingAndUngrounded:1; + bool32 thawsUser:1; + bool32 ignoresSubstitute:1; + bool32 forcePressure:1; + bool32 cantUseTwice:1; + // Ban flags + bool32 gravityBanned:1; + bool32 mirrorMoveBanned:1; + bool32 meFirstBanned:1; + bool32 mimicBanned:1; + bool32 metronomeBanned:1; + bool32 copycatBanned:1; + bool32 assistBanned:1; // Matches same moves as copycatBanned + semi-invulnerable moves and Mirror Coat. + bool32 sleepTalkBanned:1; + bool32 instructBanned:1; + bool32 encoreBanned:1; + bool32 parentalBondBanned:1; + bool32 skyBattleBanned:1; + bool32 sketchBanned:1; + u32 padding:19; + // end of word + + union { + struct { + u16 stringId; + u16 status; + } twoTurnAttack; + struct { + u16 side; + u16 property; // can be used to remove the hardcoded values + } protect; + u32 status; + u16 moveProperty; + u16 holdEffect; + u16 type; + u16 fixedDamage; + u16 absorbPercentage; + u16 maxEffect; + } argument; + + // primary/secondary effects + const struct AdditionalEffect *additionalEffects; + + // contest parameters + u8 contestEffect; + u8 contestCategory:3; + u8 contestComboStarterId; + u8 contestComboMoves[MAX_COMBO_MOVES]; + const u8 *battleAnimScript; +}; + +extern const struct MoveInfo gMovesInfo[]; +extern const u8 gNotDoneYetDescription[]; +extern const struct BattleMoveEffect gBattleMoveEffects[]; + +static inline u32 SanitizeMoveId(u32 moveId) +{ + if (moveId >= MOVES_COUNT_ALL) + return MOVE_NONE; + else + return moveId; +} + +static inline const u8 *GetMoveName(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].name; +} + +static inline const u8 *GetMoveDescription(u32 moveId) +{ + moveId = SanitizeMoveId(moveId); + if (gMovesInfo[moveId].effect == EFFECT_PLACEHOLDER) + return gNotDoneYetDescription; + return gMovesInfo[moveId].description; +} + +static inline u32 GetMoveEffect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].effect; +} + +static inline u32 GetMoveType(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].type; +} + +static inline u32 GetMoveCategory(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].category; +} + +static inline u32 GetMovePower(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].power; +} + +static inline u32 GetMoveAccuracy(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].accuracy; +} + +static inline u32 GetMoveTarget(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].target; +} + +static inline u32 GetMovePP(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].pp; +} + +static inline u32 GetMoveZEffect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].zMove.effect; +} + +static inline u32 GetMoveZPowerOverride(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].zMove.powerOverride; +} + +static inline s32 GetMovePriority(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].priority; +} + +static inline u32 GetMoveRecoil(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].recoil; +} + +static inline u32 GetMoveStrikeCount(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].strikeCount; +} + +static inline u32 GetMoveCriticalHitStage(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].criticalHitStage; +} + +static inline bool32 MoveAlwaysCrits(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].alwaysCriticalHit; +} + +static inline u32 GetMoveAdditionalEffectCount(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].numAdditionalEffects; +} + +static inline bool32 MoveMakesContact(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].makesContact; +} + +static inline bool32 MoveIgnoresProtect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoresProtect; +} + +static inline bool32 MoveCanBeBouncedBack(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].magicCoatAffected; +} + +static inline bool32 MoveCanBeSnatched(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].snatchAffected; +} + +static inline bool32 MoveIgnoresKingsRock(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoresKingsRock; +} + +static inline bool32 IsPunchingMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].punchingMove; +} + +static inline bool32 IsBitingMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].bitingMove; +} + +static inline bool32 IsPulseMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].pulseMove; +} + +static inline bool32 IsSoundMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].soundMove; +} + +static inline bool32 IsBallisticMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ballisticMove; +} + +static inline bool32 IsPowderMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].powderMove; +} + +static inline bool32 IsDanceMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].danceMove; +} + +static inline bool32 IsWindMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].windMove; +} + +static inline bool32 IsSlicingMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].slicingMove; +} + +static inline bool32 IsHealingMove(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].healingMove; +} + +static inline bool32 MoveIncreasesPowerToMinimizedTargets(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].minimizeDoubleDamage; +} + +static inline bool32 MoveIgnoresTargetAbility(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetAbility; +} + +static inline bool32 MoveIgnoresDefenseEvasionStages(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetDefenseEvasionStages; +} + +static inline bool32 MoveDamagesUnderground(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderground; +} + +static inline bool32 MoveDamagesUnderWater(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderwater; +} + +static inline bool32 MoveDamagesAirborne(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborne; +} + +static inline bool32 MoveDamagesAirborneDoubleDamage(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborneDoubleDamage; +} + +static inline bool32 MoveIgnoresTypeIfFlyingAndUngrounded(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoreTypeIfFlyingAndUngrounded; +} + +static inline bool32 MoveThawsUser(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].thawsUser; +} + +static inline bool32 MoveIgnoresSubstitute(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].ignoresSubstitute; +} + +static inline bool32 MoveForcesPressure(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].forcePressure; +} + +static inline bool32 MoveCantBeUsedTwice(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].cantUseTwice; +} + +static inline bool32 IsMoveGravityBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].gravityBanned; +} + +static inline bool32 IsMoveMirrorMoveBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].mirrorMoveBanned; +} + +static inline bool32 IsMoveMeFirstBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].meFirstBanned; +} + +static inline bool32 IsMoveMimicBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].mimicBanned; +} + +static inline bool32 IsMoveMetronomeBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].metronomeBanned; +} + +static inline bool32 IsMoveCopycatBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].copycatBanned; +} + +static inline bool32 IsMoveAssistBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].assistBanned; +} + +static inline bool32 IsMoveSleepTalkBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].sleepTalkBanned; +} + +static inline bool32 IsMoveInstructBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].instructBanned; +} + +static inline bool32 IsMoveEncoreBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].encoreBanned; +} + +static inline bool32 IsMoveParentalBondBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].parentalBondBanned; +} + +static inline bool32 IsMoveSkyBattleBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].skyBattleBanned; +} + +static inline bool32 IsMoveSketchBanned(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].sketchBanned; +} + +static inline u32 GetMoveTwoTurnAttackStringId(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.stringId; +} + +static inline u32 GetMoveTwoTurnAttackStatus(u32 moveId) +{ + return UNCOMPRESS_BITS(gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status); +} + +static inline u32 GetMoveTwoTurnAttackWeather(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status; +} + +static inline u32 GetMoveProtectSide(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.protect.side; +} + +static inline u32 GetMoveEffectArg_Status(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.status; +} + +static inline u32 GetMoveEffectArg_MoveProperty(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.moveProperty; +} + +static inline u32 GetMoveEffectArg_HoldEffect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.holdEffect; +} + +static inline u32 GetMoveArgType(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.type; +} + +static inline u32 GetMoveFixedDamage(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.fixedDamage; +} + +static inline u32 GetMoveAbsorbPercentage(u32 moveId) +{ + moveId = SanitizeMoveId(moveId); + if (gMovesInfo[moveId].argument.absorbPercentage == 0) + return 50; + return gMovesInfo[moveId].argument.absorbPercentage; +} + +static inline u32 GetMoveMaxEffect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].argument.maxEffect; +} + +static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect) +{ + return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect]; +} + +static inline u32 GetMoveContestEffect(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].contestEffect; +} + +static inline u32 GetMoveContestCategory(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].contestCategory; +} + +static inline u32 GetMoveContestComboStarter(u32 moveId) +{ + return gMovesInfo[SanitizeMoveId(moveId)].contestComboStarterId; +} + +static inline u32 GetMoveContestComboMoves(u32 moveId, u32 comboMove) +{ + return gMovesInfo[SanitizeMoveId(moveId)].contestComboMoves[comboMove]; +} + +static inline const u8 *GetMoveAnimationScript(u32 moveId) +{ + moveId = SanitizeMoveId(moveId); + if (gMovesInfo[moveId].battleAnimScript == NULL) + { + DebugPrintfLevel(MGBA_LOG_WARN, "No animation for moveId=%u", moveId); + return gMovesInfo[MOVE_NONE].battleAnimScript; + } + return gMovesInfo[moveId].battleAnimScript; +} + +static inline const u8 *GetMoveBattleScript(u32 moveId) +{ + moveId = SanitizeMoveId(moveId); + if (gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript == NULL) + { + DebugPrintfLevel(MGBA_LOG_WARN, "No effect for moveId=%u", moveId); + return gBattleMoveEffects[EFFECT_PLACEHOLDER].battleScript; + } + return gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript; +} + +#endif // GUARD_MOVES_H diff --git a/include/party_menu.h b/include/party_menu.h index a34f06cec6..5236dd27a7 100644 --- a/include/party_menu.h +++ b/include/party_menu.h @@ -27,6 +27,9 @@ extern MainCallback gPostMenuFieldCallback; extern u8 gSelectedOrderFromParty[MAX_FRONTIER_PARTY_SIZE]; extern u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2]; +extern const struct SpriteSheet gSpriteSheet_HeldItem; +extern const u16 gHeldItemPalette[]; + extern void (*gItemUseCB)(u8, TaskFunc); extern const struct SpriteTemplate gSpriteTemplate_StatusIcons; diff --git a/include/pokemon.h b/include/pokemon.h index 8a618f5fe1..f855b27ea5 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -479,103 +479,6 @@ struct SpeciesInfo /*0xC4*/ #endif //OW_POKEMON_OBJECT_EVENTS }; -struct MoveInfo -{ - const u8 *name; - const u8 *description; - u16 effect; - u16 type:5; - u16 category:2; - u16 power:9; // up to 511 - u16 accuracy:7; - u16 target:9; - u8 pp; - union { - u8 effect; - u8 powerOverride; - } zMove; - - s32 priority:4; - u32 recoil:7; - u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit. - u32 criticalHitStage:2; - u32 alwaysCriticalHit:1; - u32 numAdditionalEffects:2; // limited to 3 - don't want to get too crazy - // 12 bits left to complete this word - continues into flags - - // Flags - u32 makesContact:1; - u32 ignoresProtect:1; - u32 magicCoatAffected:1; - u32 snatchAffected:1; - u32 ignoresKingsRock:1; - u32 punchingMove:1; - u32 bitingMove:1; - u32 pulseMove:1; - u32 soundMove:1; - u32 ballisticMove:1; - u32 powderMove:1; - u32 danceMove:1; - u32 windMove:1; - u32 slicingMove:1; // end of word - u32 healingMove:1; - u32 minimizeDoubleDamage:1; - u32 ignoresTargetAbility:1; - u32 ignoresTargetDefenseEvasionStages:1; - u32 damagesUnderground:1; - u32 damagesUnderwater:1; - u32 damagesAirborne:1; - u32 damagesAirborneDoubleDamage:1; - u32 ignoreTypeIfFlyingAndUngrounded:1; - u32 thawsUser:1; - u32 ignoresSubstitute:1; - u32 forcePressure:1; - u32 cantUseTwice:1; - - // Ban flags - u32 gravityBanned:1; - u32 mirrorMoveBanned:1; - u32 meFirstBanned:1; - u32 mimicBanned:1; - u32 metronomeBanned:1; - u32 copycatBanned:1; - u32 assistBanned:1; // Matches same moves as copycatBanned + semi-invulnerable moves and Mirror Coat. - u32 sleepTalkBanned:1; - u32 instructBanned:1; - u32 encoreBanned:1; - u32 parentalBondBanned:1; - u32 skyBattleBanned:1; - u32 sketchBanned:1; - u32 padding:5; // end of word - - u32 argument; - - // primary/secondary effects - const struct AdditionalEffect *additionalEffects; - - // contest parameters - u8 contestEffect; - u8 contestCategory:3; - u8 contestComboStarterId; - u8 contestComboMoves[MAX_COMBO_MOVES]; - const u8 *battleAnimScript; -}; - -#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__} -#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ )) - -// Just a hack to make a move boosted by Sheer Force despite having no secondary effects affected -#define SHEER_FORCE_HACK { .moveEffect = 0, .chance = 100, } - -struct AdditionalEffect -{ - u16 moveEffect; - u8 self:1; - u8 onlyIfTargetRaisedStats:1; - u8 onChargeTurnOnly:1; - u8 chance; // 0% = effect certain, primary effect -}; - struct Ability { u8 name[ABILITY_NAME_LENGTH + 1]; @@ -705,7 +608,6 @@ extern struct Pokemon gEnemyParty[PARTY_SIZE]; extern struct SpriteTemplate gMultiuseSpriteTemplate; extern u16 gFollowerSteps; -extern const struct MoveInfo gMovesInfo[]; extern const u8 gFacilityClassToPicIndex[]; extern const u8 gFacilityClassToTrainerClass[]; extern const struct SpeciesInfo gSpeciesInfo[]; @@ -885,6 +787,7 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg); u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg); bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method); u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove); +void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv); bool32 SpeciesHasGenderDifferences(u16 species); bool32 TryFormChange(u32 monId, u32 side, u16 method); void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method); @@ -898,8 +801,6 @@ u16 GetCryIdBySpecies(u16 species); u16 GetSpeciesPreEvolution(u16 species); void HealPokemon(struct Pokemon *mon); void HealBoxPokemon(struct BoxPokemon *boxMon); -const u8 *GetMoveName(u16 moveId); -const u8 *GetMoveAnimationScript(u16 moveId); void UpdateDaysPassedSinceFormChange(u16 days); void TrySetDayLimitToFormChange(struct Pokemon *mon); u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler); diff --git a/include/pokemon_icon.h b/include/pokemon_icon.h index 9e51e1bc4d..3986f8948b 100644 --- a/include/pokemon_icon.h +++ b/include/pokemon_icon.h @@ -24,5 +24,6 @@ void LoadMonIconPalettePersonality(u16 species, u32 personality); void SpriteCB_MonIcon(struct Sprite *sprite); void SetPartyHPBarSprite(struct Sprite *sprite, u8 animNum); u8 GetMonIconPaletteIndexFromSpecies(u16 species); +void SafeFreeMonIconPalette(u16 species); #endif // GUARD_POKEMON_ICON_H diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h index fe299c48b4..1f286698a5 100755 --- a/include/pokemon_summary_screen.h +++ b/include/pokemon_summary_screen.h @@ -5,7 +5,6 @@ extern u8 gLastViewedMonIndex; -extern const u8 gNotDoneYetDescription[]; extern const struct SpriteTemplate gSpriteTemplate_MoveTypes; extern const struct CompressedSpriteSheet gSpriteSheet_MoveTypes; extern const struct CompressedSpriteSheet gSpriteSheet_CategoryIcons; diff --git a/include/random.h b/include/random.h index 000bc1302c..886094733a 100644 --- a/include/random.h +++ b/include/random.h @@ -176,6 +176,7 @@ enum RandomTag RNG_RANDOM_TARGET, RNG_AI_PREDICT_ABILITY, RNG_HEALER, + RNG_DEXNAV_ENCOUNTER_LEVEL, }; #define RandomWeighted(tag, ...) \ diff --git a/include/strings.h b/include/strings.h index 8e1f797079..06a3a658a2 100644 --- a/include/strings.h +++ b/include/strings.h @@ -209,6 +209,7 @@ extern const u8 gText_MenuOption[]; extern const u8 gText_MenuExit[]; extern const u8 gText_MenuRetire[]; extern const u8 gText_MenuRest[]; +extern const u8 gText_MenuDexNav[]; extern const u8 gText_Floor1[]; extern const u8 gText_Floor2[]; extern const u8 gText_Floor3[]; diff --git a/include/test/battle.h b/include/test/battle.h index 7cf7053988..1c044fd6e2 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -29,7 +29,7 @@ * * ASSUMPTIONS * { - * ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE); + * ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE); * } * * SINGLE_BATTLE_TEST("Stun Spore inflicts paralysis") @@ -87,7 +87,7 @@ * SINGLE_BATTLE_TEST("Stun Spore does not affect Grass-types") * { * GIVEN { - * ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + * ASSUME(IsPowderMove(MOVE_STUN_SPORE)); * ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); * PLAYER(SPECIES_ODDISH); // 1. * OPPONENT(SPECIES_ODDISH); // 2. @@ -129,7 +129,7 @@ * PARAMETRIZE { raiseAttack = FALSE; } * PARAMETRIZE { raiseAttack = TRUE; } * GIVEN { - * ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + * ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); * PLAYER(SPECIES_WOBBUFFET); * OPPONENT(SPECIES_WOBBUFFET); * } WHEN { @@ -176,7 +176,7 @@ * Pokémon we can observe the damage of a physical attack with and * without the burn. To document that this test assumes the attack is * physical we can use: - * ASSUME(gMovesInfo[MOVE_WHATEVER].category == DAMAGE_CATEGORY_PHYSICAL); + * ASSUME(GetMoveCategory(MOVE_WHATEVER) == DAMAGE_CATEGORY_PHYSICAL); * * ASSUMPTIONS * Should be placed immediately after any #includes and contain any @@ -186,7 +186,7 @@ * move_effect_poison_hit.c should be: * ASSUMPTIONS * { - * ASSUME(gMovesInfo[MOVE_POISON_STING].effect == EFFECT_POISON_HIT); + * ASSUME(GetMoveEffect(MOVE_POISON_STING) == EFFECT_POISON_HIT); * } * * SINGLE_BATTLE_TEST(name, results...) and DOUBLE_BATTLE_TEST(name, results...) @@ -228,7 +228,7 @@ * PARAMETRIZE { hp = 99; } * PARAMETRIZE { hp = 33; } * GIVEN { - * ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + * ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); * PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); } * OPPONENT(SPECIES_WOBBUFFET); * } WHEN { @@ -265,7 +265,7 @@ * * If the tag is not provided, runs the test 50 times and computes an * approximate pass ratio. - * PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100); + * PASSES_RANDOMLY(GetMoveAccuracy(move), 100); * Note that this mode of PASSES_RANDOMLY makes the tests run very * slowly and should be avoided where possible. If the mechanic you are * testing is missing its tag, you should add it. @@ -287,6 +287,16 @@ * GIVEN { * FLAG_SET(FLAG_SYS_EXAMPLE_FLAG); * + * WITH_CONFIG(configTag, value) + * Runs the test with a specified config override. `configTag` must be + * of `enum GenConfigTag` + * Example: + * GIVEN { + * WITH_CONFIG(GEN_CONFIG_GALE_WINGS, GEN_6); + * } + * The `value` may be inferred from a local variable, e.g. set by + * PARAMETRIZE. + * * PLAYER(species) and OPPONENT(species) * Adds the species to the player's or opponent's party respectively. * The Pokémon can be further customized with the following functions: @@ -488,6 +498,7 @@ #include "battle.h" #include "battle_anim.h" #include "data.h" +#include "generational_changes.h" #include "item.h" #include "random.h" #include "recorded_battle.h" @@ -742,7 +753,7 @@ extern struct BattleTestRunnerState *const gBattleTestRunnerState; /* Test */ #define TO_DO_BATTLE_TEST(_name) \ - TEST("TODO: " _name) \ + TEST(_name) \ { \ TO_DO; \ } @@ -822,6 +833,7 @@ struct moveWithPP { #define AI_LOG AILogScores(__LINE__) #define FLAG_SET(flagId) SetFlagForTest(__LINE__, flagId) +#define WITH_CONFIG(configTag, value) TestSetConfig(__LINE__, configTag, value) #define PLAYER(species) for (OpenPokemon(__LINE__, B_SIDE_PLAYER, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__)) #define OPPONENT(species) for (OpenPokemon(__LINE__, B_SIDE_OPPONENT, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__)) @@ -855,6 +867,7 @@ struct moveWithPP { #define Shadow(isShadow) Shadow_(__LINE__, shadow) void SetFlagForTest(u32 sourceLine, u16 flagId); +void TestSetConfig(u32 sourceLine, enum GenConfigTag configTag, u32 value); void ClearFlagAfterTest(void); void OpenPokemon(u32 sourceLine, u32 side, u32 species); void ClosePokemon(u32 sourceLine); diff --git a/include/test/test.h b/include/test/test.h index 1a9d8a237e..ccfc589c21 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -95,7 +95,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...); #define ASSUMPTIONS \ static void Assumptions(void); \ - __attribute__((section(".tests"), used)) static const struct Test sAssumptions = \ + __attribute__((section(".tests"), used, no_reorder)) static const struct Test sAssumptions = \ { \ .name = "ASSUMPTIONS: " __FILE__, \ .filename = __FILE__, \ diff --git a/include/text_window.h b/include/text_window.h index a292d1309e..98776193f6 100644 --- a/include/text_window.h +++ b/include/text_window.h @@ -25,5 +25,6 @@ void rbox_fill_rectangle(u8 windowId); const u16 *GetTextWindowPalette(u8 id); const u16 *GetOverworldTextboxPalettePtr(void); void LoadSignPostWindowFrameGfx(void); +void LoadDexNavWindowGfx(u8 windowId, u16 destOffset, u8 palOffset); #endif // GUARD_TEXT_WINDOW_H diff --git a/include/wild_encounter.h b/include/wild_encounter.h index 63289f081c..c7abb72aa1 100644 --- a/include/wild_encounter.h +++ b/include/wild_encounter.h @@ -23,6 +23,7 @@ struct WildPokemonHeader const struct WildPokemonInfo *landMonsInfo; const struct WildPokemonInfo *waterMonsInfo; const struct WildPokemonInfo *rockSmashMonsInfo; + const struct WildPokemonInfo *hiddenMonsInfo; const struct WildPokemonInfo *fishingMonsInfo; }; @@ -43,5 +44,11 @@ bool8 UpdateRepelCounter(void); bool8 TryDoDoubleWildBattle(void); bool8 StandardWildEncounter_Debug(void); u32 CalculateChainFishingShinyRolls(void); +void CreateWildMon(u16 species, u8 level); +u16 GetCurrentMapWildMonHeaderId(void); +u8 ChooseWildMonIndex_Land(void); +u8 ChooseWildMonIndex_WaterRock(void); +u8 ChooseHiddenMonIndex(void); +bool32 MapHasNoEncounterData(void); #endif // GUARD_WILD_ENCOUNTER_H diff --git a/ld_script_test.ld b/ld_script_test.ld index 8972a97b00..d279d6b4f6 100644 --- a/ld_script_test.ld +++ b/ld_script_test.ld @@ -38,7 +38,7 @@ SECTIONS { __iwram_end = .; } > IWRAM - .iwram.sbss (NOLOAD) : + .iwram.bss (NOLOAD) : ALIGN(4) { src/*.o(.bss); @@ -55,13 +55,17 @@ SECTIONS { data/*.o(COMMON); test/*.o(COMMON); *libc.a:sbrkr.o(COMMON); - . = ALIGN(4); + } > IWRAM - /* .persistent starts at 0x3007F00 */ - /* WARNING: This is the end of the IRQ stack, if there's too - * much data it WILL be overwritten. */ - . = 0x7F00; - test/*.o(.persistent); + /* .persistent starts at 0x3007F00 */ + /* WARNING: This is the end of the IRQ stack, if there's too + * much data it WILL be overwritten. */ + + . = 0x03007F00; + .iwram.persistent (NOLOAD) : + ALIGN(4) + { + test/*.o(.persistent); } > IWRAM /* BEGIN ROM DATA */ @@ -79,7 +83,7 @@ SECTIONS { script_data : ALIGN(4) { - data/*.o(script_data); + data/*.o(script_data); } > ROM =0 lib_text : @@ -114,7 +118,7 @@ SECTIONS { } > ROM =0 .data.iwram : - ALIGN(4) + ALIGN(8) { __iwram_lma = .; . = . + (__iwram_end - __iwram_start); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 99706f4d73..828b7b7c94 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -278,7 +278,7 @@ u32 BattleAI_ChooseMoveOrAction(void) ret = ChooseMoveOrAction_Doubles(sBattler_AI); // Clear protect structures, some flags may be set during AI calcs - // e.g. pranksterElevated from GetMovePriority + // e.g. pranksterElevated from GetBattleMovePriority memset(&gProtectStructs, 0, MAX_BATTLERS_COUNT * sizeof(struct ProtectStruct)); #if TESTING TestRunner_Battle_CheckAiMoveScores(sBattler_AI); @@ -399,7 +399,7 @@ static u32 Ai_SetMoveAccuracy(struct AiLogicData *aiData, u32 battlerAtk, u32 ba u32 accuracy; u32 abilityAtk = aiData->abilities[battlerAtk]; u32 abilityDef = aiData->abilities[battlerDef]; - if (abilityAtk == ABILITY_NO_GUARD || abilityDef == ABILITY_NO_GUARD || gMovesInfo[move].accuracy == 0) // Moves with accuracy 0 or no guard ability always hit. + if (abilityAtk == ABILITY_NO_GUARD || abilityDef == ABILITY_NO_GUARD || GetMoveAccuracy(move) == 0) // Moves with accuracy 0 or no guard ability always hit. accuracy = 100; else accuracy = GetTotalAccuracy(battlerAtk, battlerDef, move, abilityAtk, abilityDef, aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]); @@ -431,9 +431,9 @@ static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u3 u8 effectiveness = AI_EFFECTIVENESS_x0; move = moves[moveIndex]; - if (move != 0 - && move != 0xFFFF - //&& !IS_MOVE_STATUS(gMovesInfo[move]) /* we want to get effectiveness and accuracy of status moves */ + if (move != MOVE_NONE + && move != MOVE_UNAVAILABLE + //&& !IsBattleMoveStatus(move) /* we want to get effectiveness and accuracy of status moves */ && !(aiData->moveLimitations[battlerAtk] & (1u << moveIndex))) { dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather, rollType); @@ -661,7 +661,8 @@ static inline bool32 ShouldConsiderMoveForBattler(u32 battlerAi, u32 battlerDef, { if (battlerAi == BATTLE_PARTNER(battlerDef)) { - if (gMovesInfo[move].target == MOVE_TARGET_BOTH || gMovesInfo[move].target == MOVE_TARGET_OPPONENTS_FIELD) + u32 target = GetBattlerMoveTargetType(battlerAi, move); + if (target == MOVE_TARGET_BOTH || target == MOVE_TARGET_OPPONENTS_FIELD) return FALSE; } return TRUE; @@ -707,8 +708,8 @@ static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u3 static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { // move data - s8 atkPriority = GetMovePriority(battlerAtk, move); - u32 moveEffect = gMovesInfo[move].effect; + s8 atkPriority = GetBattleMovePriority(battlerAtk, move); + u32 moveEffect = GetMoveEffect(move); s32 moveType; u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); struct AiLogicData *aiData = AI_DATA; @@ -722,9 +723,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) return score; SetTypeBeforeUsingMove(move, battlerAtk); - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); - if (gMovesInfo[move].powderMove && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])) + if (IsPowderMove(move) && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])) RETURN_SCORE_MINUS(10); if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move)) @@ -799,11 +800,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(20); break; case ABILITY_JUSTIFIED: - if (moveType == TYPE_DARK && !IS_MOVE_STATUS(move)) + if (moveType == TYPE_DARK && !IsBattleMoveStatus(move)) RETURN_SCORE_MINUS(10); break; case ABILITY_RATTLED: - if (!IS_MOVE_STATUS(move) + if (!IsBattleMoveStatus(move) && (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG)) RETURN_SCORE_MINUS(10); break; @@ -820,7 +821,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(10); break; case ABILITY_MAGIC_BOUNCE: - if (gMovesInfo[move].magicCoatAffected) + if (MoveCanBeBouncedBack(move)) RETURN_SCORE_MINUS(20); break; case ABILITY_CONTRARY: @@ -889,7 +890,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(20); break; case ABILITY_MAGIC_BOUNCE: - if (gMovesInfo[move].magicCoatAffected && moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD)) + if (MoveCanBeBouncedBack(move) && moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD)) RETURN_SCORE_MINUS(20); break; case ABILITY_SWEET_VEIL: @@ -910,7 +911,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) // gen7+ dark type mons immune to priority->elevated moves from prankster if (B_PRANKSTER_DARK_TYPES >= GEN_7 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) - && aiData->abilities[battlerAtk] == ABILITY_PRANKSTER && IS_MOVE_STATUS(move) + && aiData->abilities[battlerAtk] == ABILITY_PRANKSTER && IsBattleMoveStatus(move) && !(moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER))) RETURN_SCORE_MINUS(10); @@ -936,7 +937,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) // the following checks apply to any target (including user) // throat chop check - if (gDisableStructs[battlerAtk].throatChopTimer && gMovesInfo[move].soundMove) + if (gDisableStructs[battlerAtk].throatChopTimer && IsSoundMove(move)) return 0; // Can't even select move at all // heal block check if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move)) @@ -955,7 +956,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) RETURN_SCORE_MINUS(30); } - if (!IS_MOVE_STATUS(move)) + if (!IsBattleMoveStatus(move)) { if (weather & B_WEATHER_SUN_PRIMAL) { @@ -974,7 +975,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) switch (moveEffect) { case EFFECT_HIT: // only applies to Vital Throw - if (gMovesInfo[move].priority < 0 && AI_IsFaster(battlerAtk, battlerDef, move) && aiData->hpPercents[battlerAtk] < 40) + if (GetBattleMovePriority(battlerAtk, move) < 0 && AI_IsFaster(battlerAtk, battlerDef, move) && aiData->hpPercents[battlerAtk] < 40) ADJUST_SCORE(-2); // don't want to move last break; default: @@ -1696,7 +1697,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (!isDoubleBattle || !IsBattlerAlive(BATTLE_PARTNER(battlerAtk)) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove) - || (aiData->partnerMove != MOVE_NONE && IS_MOVE_STATUS(aiData->partnerMove)) + || (aiData->partnerMove != MOVE_NONE && IsBattleMoveStatus(aiData->partnerMove)) || *(gBattleStruct->monToSwitchIntoId + BATTLE_PARTNER(battlerAtk)) != PARTY_SIZE) //Partner is switching out. ADJUST_SCORE(-10); break; @@ -1792,7 +1793,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_CONVERSION: //Check first move type - if (IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[gBattleMons[battlerAtk].moves[0]].type)) + if (IS_BATTLER_OF_TYPE(battlerAtk, GetMoveType(gBattleMons[battlerAtk].moves[0]))) ADJUST_SCORE(-10); break; case EFFECT_REST: @@ -1883,7 +1884,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_HEAL_BELL: - if (!AnyPartyMemberStatused(battlerAtk, gMovesInfo[move].soundMove) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove)) + if (!AnyPartyMemberStatused(battlerAtk, IsSoundMove(move)) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove)) ADJUST_SCORE(-10); break; case EFFECT_ENDURE: @@ -1985,7 +1986,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (isDoubleBattle) { - if (IsHazardMoveEffect(gMovesInfo[aiData->partnerMove].effect) // partner is going to set up hazards + if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // partner is going to set up hazards && AI_IsFaster(BATTLE_PARTNER(battlerAtk), battlerAtk, aiData->partnerMove)) // partner is going to set up before the potential Defog { ADJUST_SCORE(-10); @@ -2015,7 +2016,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_SEMI_INVULNERABLE: if (predictedMove != MOVE_NONE && AI_IsSlower(battlerAtk, battlerDef, move) - && gMovesInfo[predictedMove].effect == EFFECT_SEMI_INVULNERABLE) + && GetMoveEffect(predictedMove) == EFFECT_SEMI_INVULNERABLE) ADJUST_SCORE(-10); // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you if (BattlerWillFaintFromWeather(battlerAtk, aiData->abilities[battlerAtk]) @@ -2247,7 +2248,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (isDoubleBattle && gBattleMons[BATTLE_PARTNER(battlerAtk)].hp > 0) { if (aiData->partnerMove != MOVE_NONE - && gMovesInfo[aiData->partnerMove].effect == EFFECT_PLEDGE + && GetMoveEffect(aiData->partnerMove) == EFFECT_PLEDGE && move != aiData->partnerMove) // Different pledge moves { if (gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & (STATUS1_SLEEP | STATUS1_FREEZE)) @@ -2435,7 +2436,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) instructedMove = gLastMoves[battlerDef]; if (instructedMove == MOVE_NONE - || gMovesInfo[instructedMove].instructBanned + || IsMoveInstructBanned(instructedMove) || MoveHasAdditionalEffectSelf(instructedMove, MOVE_EFFECT_RECHARGE) || IsZMove(instructedMove) || (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF) @@ -2482,7 +2483,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_SUCKER_PUNCH: if (predictedMove != MOVE_NONE) { - if (IS_MOVE_STATUS(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first + if (IsBattleMoveStatus(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first ADJUST_SCORE(-10); } break; @@ -2523,8 +2524,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-4); break; //TODO - //case EFFECT_PLASMA_FISTS: - //break; //case EFFECT_SHELL_TRAP: //break; //case EFFECT_BEAK_BLAST: @@ -2583,7 +2582,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_UPPER_HAND: - if (predictedMove == MOVE_NONE || IS_MOVE_STATUS(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move) || GetMovePriority(battlerDef, predictedMove) < 1 || GetMovePriority(battlerDef, predictedMove) > 3) // Opponent going first or not using priority move + if (predictedMove == MOVE_NONE || IsBattleMoveStatus(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move) || GetBattleMovePriority(battlerDef, predictedMove) < 1 || GetBattleMovePriority(battlerDef, predictedMove) > 3) // Opponent going first or not using priority move ADJUST_SCORE(-10); break; case EFFECT_PLACEHOLDER: @@ -2619,10 +2618,10 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)) return score; - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) return score; // status moves aren't accounted here - if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, movesetIndex, 0) && gMovesInfo[move].effect != EFFECT_EXPLOSION) + if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, movesetIndex, 0) && GetMoveEffect(move) != EFFECT_EXPLOSION) { if (AI_IsFaster(battlerAtk, battlerDef, move)) ADJUST_SCORE(FAST_KILL); @@ -2631,7 +2630,7 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } else if (CanTargetFaintAi(battlerDef, battlerAtk) && GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) != AI_IS_FASTER - && GetMovePriority(battlerAtk, move) > 0) + && GetBattleMovePriority(battlerAtk, move) > 0) { ADJUST_SCORE(LAST_CHANCE); } @@ -2643,29 +2642,30 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { // move data - u32 moveType = gMovesInfo[move].type; - u32 effect = gMovesInfo[move].effect; + u32 moveType = GetMoveType(move); + u32 effect = GetMoveEffect(move); u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); // ally data u32 battlerAtkPartner = BATTLE_PARTNER(battlerAtk); struct AiLogicData *aiData = AI_DATA; u32 atkPartnerAbility = aiData->abilities[BATTLE_PARTNER(battlerAtk)]; u32 atkPartnerHoldEffect = aiData->holdEffects[BATTLE_PARTNER(battlerAtk)]; - bool32 partnerProtecting = (gMovesInfo[aiData->partnerMove].effect == EFFECT_PROTECT); + u32 partnerEffect = GetMoveEffect(aiData->partnerMove); + bool32 partnerProtecting = (partnerEffect == EFFECT_PROTECT); bool32 attackerHasBadAbility = (gAbilitiesInfo[aiData->abilities[battlerAtk]].aiRating < 0); bool32 partnerHasBadAbility = (gAbilitiesInfo[atkPartnerAbility].aiRating < 0); u32 predictedMove = aiData->lastUsedMove[battlerDef]; SetTypeBeforeUsingMove(move, battlerAtk); - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); // check what effect partner is using if (aiData->partnerMove != 0) { - switch (gMovesInfo[aiData->partnerMove].effect) + switch (partnerEffect) { case EFFECT_HELPING_HAND: - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) ADJUST_SCORE(-7); break; case EFFECT_PERISH_SONG: @@ -2689,7 +2689,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } // check partner move effect // Adjust for always crit moves - if (gMovesInfo[aiData->partnerMove].alwaysCriticalHit && aiData->abilities[battlerAtk] == ABILITY_ANGER_POINT) + if (MoveAlwaysCrits(aiData->partnerMove) && aiData->abilities[battlerAtk] == ABILITY_ANGER_POINT) { if (AI_IsSlower(battlerAtk, battlerAtkPartner, move)) // Partner moving first { @@ -2697,7 +2697,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (IsAttackBoostMoveEffect(effect)) ADJUST_SCORE(-3); // encourage moves hitting multiple opponents - if (!IS_MOVE_STATUS(move) && (moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) + if (!IsBattleMoveStatus(move) && (moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) ADJUST_SCORE(GOOD_EFFECT); } } @@ -2726,7 +2726,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-5); else if (atkPartnerHoldEffect == HOLD_EFFECT_SCOPE_LENS || IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_DRAGON) - || gMovesInfo[aiData->partnerMove].criticalHitStage > 0 + || GetMoveCriticalHitStage(aiData->partnerMove) > 0 || HasMoveWithCriticalHitChance(battlerAtkPartner)) ADJUST_SCORE(GOOD_EFFECT); break; @@ -2779,7 +2779,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) switch (atkPartnerAbility) { case ABILITY_ANGER_POINT: - if (gMovesInfo[move].alwaysCriticalHit == TRUE + if (MoveAlwaysCrits(move) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) && AI_IsFaster(battlerAtk, battlerAtkPartner, move) && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) @@ -2850,7 +2850,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case ABILITY_JUSTIFIED: if (moveType == TYPE_DARK - && !IS_MOVE_STATUS(move) + && !IsBattleMoveStatus(move) && HasMoveWithCategory(battlerAtkPartner, DAMAGE_CATEGORY_PHYSICAL) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) @@ -2859,7 +2859,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case ABILITY_RATTLED: - if (!IS_MOVE_STATUS(move) + if (!IsBattleMoveStatus(move) && (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED) && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) @@ -2916,7 +2916,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_BEAT_UP: if (atkPartnerAbility == ABILITY_JUSTIFIED && moveType == TYPE_DARK - && !IS_MOVE_STATUS(move) + && !IsBattleMoveStatus(move) && HasMoveWithCategory(battlerAtkPartner, DAMAGE_CATEGORY_PHYSICAL) && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) && !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0)) @@ -2986,7 +2986,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) instructedMove = gLastMoves[battlerAtkPartner]; if (instructedMove != MOVE_NONE - && !IS_MOVE_STATUS(instructedMove) + && !IsBattleMoveStatus(instructedMove) && (GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves { RETURN_SCORE_PLUS(WEAK_EFFECT); @@ -2997,7 +2997,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (AI_IsSlower(battlerAtkPartner, FOE(battlerAtkPartner), aiData->partnerMove) // Opponent mon 1 goes before partner || AI_IsSlower(battlerAtkPartner, BATTLE_PARTNER(FOE(battlerAtkPartner)), aiData->partnerMove)) // Opponent mon 2 goes before partner { - if (gMovesInfo[aiData->partnerMove].effect == EFFECT_COUNTER || gMovesInfo[aiData->partnerMove].effect == EFFECT_MIRROR_COAT) + if (partnerEffect == EFFECT_COUNTER || partnerEffect == EFFECT_MIRROR_COAT) break; // These moves need to go last RETURN_SCORE_PLUS(WEAK_EFFECT); } @@ -3071,7 +3071,7 @@ static inline bool32 ShouldUseSpreadDamageMove(u32 battlerAtk, u32 move, u32 mov return (IsDoubleBattle() && noOfHitsToFaintPartner != 0 // Immunity check && IsBattlerAlive(partnerBattler) - && gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY + && GetBattlerMoveTargetType(battlerAtk, move) == MOVE_TARGET_FOES_AND_ALLY && !(noOfHitsToFaintPartner < 4 && hitsToFaintOpposingBattler == 1) && noOfHitsToFaintPartner < 7); } @@ -3090,7 +3090,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && gMovesInfo[moves[i]].power) + if (moves[i] != MOVE_NONE && GetMovePower(moves[i]) != 0) { noOfHits[i] = GetNoOfHitsToKOBattler(battlerAtk, battlerDef, i); if (ShouldUseSpreadDamageMove(battlerAtk,moves[i], i, noOfHits[i])) @@ -3182,27 +3182,28 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId) static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) { // move data - u32 moveEffect = gMovesInfo[move].effect; + u32 moveEffect = GetMoveEffect(move); struct AiLogicData *aiData = AI_DATA; u32 movesetIndex = AI_THINKING_STRUCT->movesetIndex; u32 effectiveness = aiData->effectiveness[battlerAtk][battlerDef][movesetIndex]; s32 score = 0; u32 predictedMove = aiData->lastUsedMove[battlerDef]; + u32 predictedType = GetMoveType(predictedMove); u32 predictedMoveSlot = GetMoveSlot(GetMovesArray(battlerDef), predictedMove); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); u32 i; // The AI should understand that while Dynamaxed, status moves function like Protect. - if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX && gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS) + if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX && GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS) moveEffect = EFFECT_PROTECT; // check status move preference - if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_PREFER_STATUS_MOVES && IsBattleMoveStatus(move) && effectiveness != AI_EFFECTIVENESS_x0) ADJUST_SCORE(10); // check thawing moves - if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && gMovesInfo[move].thawsUser) + if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && MoveThawsUser(move)) ADJUST_SCORE(10); // check burn / frostbite @@ -3391,7 +3392,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) score += AI_TryToClearStats(battlerAtk, battlerDef, isDoubleBattle); break; case EFFECT_ROAR: - if ((gMovesInfo[move].soundMove && aiData->abilities[battlerDef] == ABILITY_SOUNDPROOF) + if ((IsSoundMove(move) && aiData->abilities[battlerDef] == ABILITY_SOUNDPROOF) || aiData->abilities[battlerDef] == ABILITY_SUCTION_CUPS) break; else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX) @@ -3407,7 +3408,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(-2); break; case EFFECT_CONVERSION: - if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[gBattleMons[battlerAtk].moves[0]].type)) + if (!IS_BATTLER_OF_TYPE(battlerAtk, GetMoveType(gBattleMons[battlerAtk].moves[0]))) ADJUST_SCORE(WEAK_EFFECT); break; case EFFECT_SWALLOW: @@ -3584,7 +3585,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) break; else if (gDisableStructs[battlerDef].encoreTimer == 0 && (B_MENTAL_HERB < GEN_5 || aiData->holdEffects[battlerDef] != HOLD_EFFECT_MENTAL_HERB) - && (gBattleMoveEffects[gMovesInfo[gLastMoves[battlerDef]].effect].encourageEncore)) + && (gBattleMoveEffects[GetMoveEffect(gLastMoves[battlerDef])].encourageEncore)) ADJUST_SCORE(BEST_EFFECT); break; case EFFECT_SLEEP_TALK: @@ -3632,7 +3633,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) switch (move) { case MOVE_QUICK_GUARD: - if (predictedMove != MOVE_NONE && gMovesInfo[predictedMove].priority > 0) + if (predictedMove != MOVE_NONE && GetMovePriority(predictedMove) > 0) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_WIDE_GUARD: @@ -3647,13 +3648,13 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } break; case MOVE_CRAFTY_SHIELD: - if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) + if (predictedMove != MOVE_NONE && IsBattleMoveStatus(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_MAT_BLOCK: if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE - && !IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) + && !IsBattleMoveStatus(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); break; case MOVE_KINGS_SHIELD: @@ -3801,10 +3802,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case EFFECT_SEMI_INVULNERABLE: if (predictedMove != MOVE_NONE && !isDoubleBattle) { + u32 predictedEffect = GetMoveEffect(predictedMove); if ((AI_IsFaster(battlerAtk, battlerDef, move)) - && (gMovesInfo[predictedMove].effect == EFFECT_EXPLOSION || gMovesInfo[predictedMove].effect == EFFECT_PROTECT)) + && (predictedEffect == EFFECT_EXPLOSION || predictedEffect == EFFECT_PROTECT)) ADJUST_SCORE(GOOD_EFFECT); - else if (gMovesInfo[predictedMove].effect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) + else if (predictedEffect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) ADJUST_SCORE(GOOD_EFFECT); } break; @@ -3876,7 +3878,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) { if (isDoubleBattle) { - if (IsHazardMoveEffect(gMovesInfo[aiData->partnerMove].effect) // Partner is going to set up hazards + if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // Partner is going to set up hazards && AI_IsSlower(battlerAtk, BATTLE_PARTNER(battlerAtk), move)) // Partner going first break; // Don't use Defog if partner is going to set up hazards } @@ -3897,7 +3899,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) { u32 predictedMoveOnPartner = gLastMoves[BATTLE_PARTNER(battlerAtk)]; - if (predictedMoveOnPartner != MOVE_NONE && !IS_MOVE_STATUS(predictedMoveOnPartner)) + if (predictedMoveOnPartner != MOVE_NONE && !IsBattleMoveStatus(predictedMoveOnPartner)) ADJUST_SCORE(GOOD_EFFECT); } break; @@ -3908,7 +3910,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPDEF)); break; case EFFECT_TAUNT: - if (IS_MOVE_STATUS(predictedMove)) + if (IsBattleMoveStatus(predictedMove)) ADJUST_SCORE(GOOD_EFFECT); else if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_STATUS)) ADJUST_SCORE(DECENT_EFFECT); @@ -3972,7 +3974,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); // Force 'em out next turn break; default: - if (gMovesInfo[move].effect != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE && aiData->items[battlerDef] != ITEM_NONE) + if (GetMoveEffect(move) != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE && aiData->items[battlerDef] != ITEM_NONE) { switch (aiData->holdEffects[battlerDef]) { @@ -4033,7 +4035,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(GOOD_EFFECT); break; case EFFECT_MAGIC_COAT: - if (IS_MOVE_STATUS(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) + if (IsBattleMoveStatus(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) ADJUST_SCORE(GOOD_EFFECT); break; case EFFECT_RECYCLE: @@ -4113,7 +4115,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case EFFECT_GRUDGE: break; case EFFECT_SNATCH: - if (predictedMove != MOVE_NONE && gMovesInfo[predictedMove].snatchAffected) + if (predictedMove != MOVE_NONE && MoveCanBeSnatched(predictedMove)) ADJUST_SCORE(GOOD_EFFECT); // Steal move break; case EFFECT_MUD_SPORT: @@ -4280,7 +4282,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) if ((aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB || aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE || (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD)) - && gMovesInfo[predictedMove].type == TYPE_NORMAL) + && predictedType == TYPE_NORMAL) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_FLING: @@ -4311,7 +4313,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_POWDER: - if (predictedMove != MOVE_NONE && !IS_MOVE_STATUS(predictedMove) && gMovesInfo[predictedMove].type == TYPE_FIRE) + if (predictedMove != MOVE_NONE && !IsBattleMoveStatus(predictedMove) && predictedType == TYPE_FIRE) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_TELEKINESIS: @@ -4327,7 +4329,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_SOAK: - if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && gMovesInfo[move].argument == TYPE_WATER) ) + if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && GetMoveArgType(move) == TYPE_WATER) ) ADJUST_SCORE(DECENT_EFFECT); // Get some super effective moves break; case EFFECT_THIRD_TYPE: @@ -4369,7 +4371,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) { if (AI_IsFaster(battlerAtk, battlerDef, move)) // Attacker goes first { - if (gMovesInfo[predictedMove].type == TYPE_GROUND) + if (predictedType == TYPE_GROUND) ADJUST_SCORE(GOOD_EFFECT); // Cause the enemy's move to fail break; } @@ -4383,7 +4385,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) break; case EFFECT_CAMOUFLAGE: if (predictedMove != MOVE_NONE && AI_IsFaster(battlerAtk, battlerDef, move) // Attacker goes first - && !IS_MOVE_STATUS(move) && AI_GetMoveEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0) + && !IsBattleMoveStatus(move) && AI_GetMoveEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0) ADJUST_SCORE(DECENT_EFFECT); break; case EFFECT_TOXIC_THREAD: @@ -4437,34 +4439,32 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) || gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY) ADJUST_SCORE(GOOD_EFFECT); break; - case EFFECT_SALT_CURE: - if (IS_BATTLER_ANY_TYPE(battlerDef, TYPE_WATER, TYPE_STEEL)) - ADJUST_SCORE(DECENT_EFFECT); - break; } // move effect checks + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); // check move additional effects that are likely to happen - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + for (i = 0; i < additionalEffectCount; i++) { + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); // Only consider effects with a guaranteed chance to happen - if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], &gMovesInfo[move].additionalEffects[i])) + if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], additionalEffect)) continue; // Consider move effects that target self - if (gMovesInfo[move].additionalEffects[i].self) + if (additionalEffect->self) { u32 StageStatId; if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_DEF_PLUS_1: case MOVE_EFFECT_SPD_PLUS_1: case MOVE_EFFECT_SP_ATK_PLUS_1: case MOVE_EFFECT_SP_DEF_PLUS_1: - StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; + StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_PLUS_1; ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId)); break; case MOVE_EFFECT_ATK_PLUS_2: @@ -4472,7 +4472,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case MOVE_EFFECT_SPD_PLUS_2: case MOVE_EFFECT_SP_ATK_PLUS_2: case MOVE_EFFECT_SP_DEF_PLUS_2: - StageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1; + StageStatId = STAT_CHANGE_ATK_2 + additionalEffect->moveEffect - MOVE_EFFECT_ATK_PLUS_1; ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId)); break; case MOVE_EFFECT_ACC_PLUS_1: @@ -4492,14 +4492,14 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } else { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_ATK_MINUS_1: case MOVE_EFFECT_DEF_MINUS_1: case MOVE_EFFECT_SPD_MINUS_1: case MOVE_EFFECT_SP_ATK_MINUS_1: case MOVE_EFFECT_SP_DEF_MINUS_1: - StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1; + StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1; ADJUST_SCORE(IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId)); break; case MOVE_EFFECT_ATK_MINUS_2: @@ -4507,7 +4507,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case MOVE_EFFECT_SPD_MINUS_2: case MOVE_EFFECT_SP_ATK_MINUS_2: case MOVE_EFFECT_SP_DEF_MINUS_2: - StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2; + StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2; ADJUST_SCORE(IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId)); break; case MOVE_EFFECT_ACC_MINUS_1: @@ -4536,7 +4536,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } else // consider move effects that hinder the target { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_FLINCH: score += ShouldTryToFlinch(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move); @@ -4669,11 +4669,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } break; case MOVE_EFFECT_FEINT: - if (gMovesInfo[predictedMove].effect == EFFECT_PROTECT) + if (GetMoveEffect(predictedMove) == EFFECT_PROTECT) ADJUST_SCORE(GOOD_EFFECT); break; case MOVE_EFFECT_THROAT_CHOP: - if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].soundMove) + if (IsSoundMove(GetBestDmgMoveFromBattler(battlerDef, battlerAtk))) { if (AI_IsFaster(battlerAtk, battlerDef, move)) ADJUST_SCORE(GOOD_EFFECT); @@ -4685,6 +4685,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) if (!HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move)) ADJUST_SCORE(BEST_EFFECT); break; + case MOVE_EFFECT_SALT_CURE: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_WATER) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL)) + ADJUST_SCORE(DECENT_EFFECT); + break; + } } } @@ -4699,7 +4704,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)) return score; - if (gMovesInfo[move].power) + if (GetMovePower(move) != 0) { if (GetNoOfHitsToKOBattler(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex) == 0) ADJUST_AND_RETURN_SCORE(NO_DAMAGE_OR_FAILS); // No point in checking the move further so return early @@ -4728,13 +4733,13 @@ static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING && AI_IsSlower(battlerAtk, battlerDef, move) && CanTargetFaintAi(battlerDef, battlerAtk) - && GetMovePriority(battlerAtk, move) == 0) + && GetBattleMovePriority(battlerAtk, move) == 0) { RETURN_SCORE_MINUS(20); // No point in setting up if you will faint. Should just switch if possible.. } // check effects to prioritize first turn - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_ATTACK_UP: case EFFECT_ATTACK_UP_USER_ALLY: @@ -4826,9 +4831,11 @@ static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 { // TEMPORARY - should applied to all moves regardless of EFFECT // Consider move effects - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + for (i = 0; i < additionalEffectCount; i++) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_STEALTH_ROCK: case MOVE_EFFECT_SPIKES: @@ -4855,11 +4862,11 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)) return score; - if (gMovesInfo[move].criticalHitStage > 0) + if (GetMoveCriticalHitStage(move) > 0) ADJUST_SCORE(DECENT_EFFECT); // +3 Score - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_COUNTER: if (gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack + 10) @@ -4898,9 +4905,11 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { // TEMPORARY - should applied to all moves regardless of EFFECT // Consider move effects - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + for (i = 0; i < additionalEffectCount; i++) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_ALL_STATS_UP: if (Random() & 1) @@ -4937,12 +4946,14 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor { if (IS_TARGETING_PARTNER(battlerAtk, battlerDef) || CountUsablePartyMons(battlerAtk) == 0 - || !IS_MOVE_STATUS(move) + || !IsBattleMoveStatus(move) || !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS) || IsBattlerTrapped(battlerAtk, TRUE)) return score; - if (IsStatRaisingEffect(gMovesInfo[move].effect)) + u32 effect = GetMoveEffect(move); + + if (IsStatRaisingEffect(effect)) { if (gBattleResults.battleTurnCounter == 0) ADJUST_SCORE(GOOD_EFFECT); @@ -4953,7 +4964,7 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor } // other specific checks - switch (gMovesInfo[move].effect) + switch (effect) { case EFFECT_INGRAIN: if (!(gStatuses3[battlerAtk] & STATUS3_ROOTED)) @@ -4985,11 +4996,11 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { - u32 effect = gMovesInfo[move].effect; + u32 effect = GetMoveEffect(move); u32 moveType = 0; SetTypeBeforeUsingMove(move, battlerAtk); - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)) { @@ -5167,7 +5178,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) else { // low HP - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) ADJUST_SCORE(-2); // don't use status moves if target is at low health } } @@ -5177,9 +5188,9 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) { - u32 moveEffect = gMovesInfo[move].effect; + u32 moveEffect = GetMoveEffect(move); - if (gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS || gMovesInfo[AI_DATA->partnerMove].effect == moveEffect) + if (GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS || GetMoveEffect(AI_DATA->partnerMove) == moveEffect) return score; switch (moveEffect) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 5547351ec1..7de2e897a5 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -108,7 +108,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) for (i = 0; i < MAX_MON_MOVES; i++) { aiMove = gBattleMons[battler].moves[i]; - aiMoveEffect = gMovesInfo[aiMove].effect; + aiMoveEffect = GetMoveEffect(aiMove); if (aiMove != MOVE_NONE) { // Check if mon has an "important" status move @@ -123,7 +123,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) } // Only check damage if it's a damaging move - if (!IS_MOVE_STATUS(aiMove)) + if (!IsBattleMoveStatus(aiMove)) { // Check if mon has a super effective move if (AI_GetMoveEffectiveness(aiMove, battler, opposingBattler) >= AI_EFFECTIVENESS_x2) @@ -156,7 +156,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) for (i = 0; i < MAX_MON_MOVES; i++) { playerMove = gBattleMons[opposingBattler].moves[i]; - if (playerMove != MOVE_NONE && !IS_MOVE_STATUS(playerMove)) + if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove)) { damageTaken = AI_CalcDamage(playerMove, opposingBattler, battler, &effectiveness, FALSE, weather, DMG_ROLL_HIGHEST).expected; if (damageTaken > maxDamageTaken) @@ -332,7 +332,9 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler) u16 monAbility; u32 opposingBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(battler))); u32 incomingMove = AI_DATA->lastUsedMove[opposingBattler]; + u32 incomingType = GetMoveType(incomingMove); u32 predictedMove = incomingMove; // Update for move prediction + u32 predictedType = GetMoveType(predictedMove); bool32 isOpposingBattlerChargingOrInvulnerable = (IsSemiInvulnerable(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove)); s32 i, j; @@ -356,34 +358,34 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler) } // Create an array of possible absorb abilities so the AI considers all of them - if (gMovesInfo[predictedMove].type == TYPE_FIRE) + if (predictedType == TYPE_FIRE) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_FLASH_FIRE; } - else if (gMovesInfo[predictedMove].type == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_WATER)) + else if (predictedType == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_WATER)) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WATER_ABSORB; absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_DRY_SKIN; if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_STORM_DRAIN; } - else if (gMovesInfo[predictedMove].type == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_ELECTRIC)) + else if (predictedType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC)) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_VOLT_ABSORB; absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_MOTOR_DRIVE; if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LIGHTNING_ROD; } - else if (gMovesInfo[predictedMove].type == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_GRASS)) + else if (predictedType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS)) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SAP_SIPPER; } - else if (gMovesInfo[predictedMove].type == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_GROUND)) + else if (predictedType == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GROUND)) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_EARTH_EATER; absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LEVITATE; } - else if (gMovesInfo[predictedMove].soundMove || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].soundMove)) + else if (IsSoundMove(predictedMove) || (isOpposingBattlerChargingOrInvulnerable && IsSoundMove(incomingMove))) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SOUNDPROOF; } @@ -702,7 +704,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 perc return FALSE; if (gLastHitBy[battler] == 0xFF) return FALSE; - if (IS_MOVE_STATUS(gLastLandedMoves[battler])) + if (IsBattleMoveStatus(gLastLandedMoves[battler])) return FALSE; if (IsDoubleBattle()) @@ -812,9 +814,10 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) for (j = 0; j < MAX_MON_MOVES; j++) { aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL); + u32 aiEffect = GetMoveEffect(aiMove); if (MoveHasAdditionalEffectSelf(aiMove, MOVE_EFFECT_RAPID_SPIN) - || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && gMovesInfo[aiMove].effect == EFFECT_DEFOG) - || gMovesInfo[aiMove].effect == EFFECT_TIDY_UP) + || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && aiEffect == EFFECT_DEFOG) + || aiEffect == EFFECT_TIDY_UP) { // Have a mon that can clear the hazards, so switching out is okay return TRUE; @@ -841,7 +844,7 @@ static bool32 ShouldSwitchIfEncored(u32 battler) return FALSE; // Switch out if status move - if (gMovesInfo[encoredMove].category == DAMAGE_CATEGORY_STATUS) + if (GetMoveCategory(encoredMove) == DAMAGE_CATEGORY_STATUS) return SetSwitchinAndSwitch(battler, PARTY_SIZE); // Stay in if effective move @@ -861,7 +864,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(u32 battler) if (HOLD_EFFECT_CHOICE(holdEffect) && gBattleMons[battler].ability != ABILITY_KLUTZ) { - if (gMovesInfo[gLastUsedMove].category == DAMAGE_CATEGORY_STATUS) + if (GetMoveCategory(gLastUsedMove) == DAMAGE_CATEGORY_STATUS) return SetSwitchinAndSwitch(battler, PARTY_SIZE); } @@ -922,7 +925,6 @@ bool32 ShouldSwitch(u32 battler) struct Pokemon *party; s32 i; s32 availableToSwitch; - bool32 hasAceMon = FALSE; if (gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) return FALSE; @@ -970,21 +972,13 @@ bool32 ShouldSwitch(u32 battler) if (i == gBattleStruct->monToSwitchIntoId[battlerIn2]) continue; if (IsAceMon(battler, i)) - { - hasAceMon = TRUE; continue; - } availableToSwitch++; } if (availableToSwitch == 0) - { - if (hasAceMon) // If the ace mon is the only available mon, use it - availableToSwitch++; - else return FALSE; - } // NOTE: The sequence of the below functions matter! Do not change unless you have carefully considered the outcome. // Since the order is sequencial, and some of these functions prompt switch to specific party members. @@ -1242,7 +1236,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva for (j = 0; j < MAX_MON_MOVES; j++) { aiMove = AI_DATA->switchinCandidate.battleMon.moves[j]; - if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove)) + if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove)) { aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j); dmg = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, rollType); @@ -1289,10 +1283,10 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon { // Stealth Rock if ((hazardFlags & SIDE_STATUS_STEALTH_ROCK) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS) - hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_STEALTH_ROCK].type, defType1, defType2, battleMon->maxHP); + hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), defType1, defType2, battleMon->maxHP); // G-Max Steelsurge if ((hazardFlags & SIDE_STATUS_STEELSURGE) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS) - hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_G_MAX_STEELSURGE].type, defType1, defType2, battleMon->maxHP); + hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_G_MAX_STEELSURGE), defType1, defType2, battleMon->maxHP); // Spikes if ((hazardFlags & SIDE_STATUS_SPIKES) && IsMonGrounded(heldItemEffect, ability, defType1, defType2)) { @@ -1698,7 +1692,7 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle for (i = 0; i < MAX_MON_MOVES; i++) { playerMove = gBattleMons[opposingBattler].moves[i]; - if (playerMove != MOVE_NONE && !IS_MOVE_STATUS(playerMove)) + if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove)) { damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, FALSE, DMG_ROLL_HIGHEST); if (damageTaken > maxDamageTaken) @@ -1734,7 +1728,7 @@ static inline bool32 IsFreeSwitch(bool32 isSwitchAfterKO, u32 battlerSwitchingOu // Switch out effects if (!IsDoubleBattle()) // Not handling doubles' additional complexity { - if (IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect) && movedSecond) + if (IsSwitchOutEffect(GetMoveEffect(gLastUsedMove)) && movedSecond) return TRUE; if (AI_DATA->ejectButtonSwitch) return TRUE; @@ -1775,7 +1769,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, { int revengeKillerId = PARTY_SIZE, slowRevengeKillerId = PARTY_SIZE, fastThreatenId = PARTY_SIZE, slowThreatenId = PARTY_SIZE, damageMonId = PARTY_SIZE; int batonPassId = PARTY_SIZE, typeMatchupId = PARTY_SIZE, typeMatchupEffectiveId = PARTY_SIZE, defensiveMonId = PARTY_SIZE, aceMonId = PARTY_SIZE, trapperId = PARTY_SIZE; - int i, j, aliveCount = 0, bits = 0; + int i, j, aliveCount = 0, bits = 0, aceMonCount = 0; s32 defensiveMonHitKOThreshold = 3; // 3HKO threshold that candidate defensive mons must exceed s32 playerMonHP = gBattleMons[opposingBattler].hp, maxDamageDealt = 0, damageDealt = 0; u32 aiMove, hitsToKOAI, maxHitsToKO = 0; @@ -1798,6 +1792,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, else if (IsAceMon(battler, i)) { aceMonId = i; + aceMonCount++; continue; } else @@ -1826,7 +1821,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, { aiMove = AI_DATA->switchinCandidate.battleMon.moves[j]; - if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove)) + if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove)) { if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_CONSERVATIVE) damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, DMG_ROLL_LOWEST); @@ -1856,7 +1851,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, } // Check for mon with resistance and super effective move for best type matchup mon with effective move - if (aiMove != MOVE_NONE && !IS_MOVE_STATUS(aiMove)) + if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove)) { if (typeMatchup < bestResistEffective) { @@ -1871,7 +1866,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, } // If a self destruction move doesn't OHKO, don't factor it into revenge killing - if (gMovesInfo[aiMove].effect == EFFECT_EXPLOSION && damageDealt < playerMonHP) + if (GetMoveEffect(aiMove) == EFFECT_EXPLOSION && damageDealt < playerMonHP) continue; // Check that mon isn't one shot and set best damage mon @@ -1944,7 +1939,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, else if (batonPassId != PARTY_SIZE) return batonPassId; } // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon. - if (aceMonId != PARTY_SIZE && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect)) + if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(GetMoveEffect(gLastUsedMove))) return aceMonId; return PARTY_SIZE; @@ -2022,7 +2017,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) // This all handled by the GetBestMonIntegrated function if the AI_FLAG_SMART_MON_CHOICES flag is set else { - s32 i, aliveCount = 0; + s32 i, aliveCount = 0, aceMonCount = 0; u32 invalidMons = 0, aceMonId = PARTY_SIZE; // Get invalid slots ids. for (i = firstId; i < lastId; i++) @@ -2039,6 +2034,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) else if (IsAceMon(battler, i)) // Save Ace Pokemon for last. { aceMonId = i; + aceMonCount++; invalidMons |= 1u << i; } else @@ -2058,8 +2054,8 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) if (bestMonId != PARTY_SIZE) return bestMonId; - // If ace mon is the last available Pokemon and switch move was used - switch to the mon. - if (aceMonId != PARTY_SIZE) + // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon. + if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect)) return aceMonId; return PARTY_SIZE; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 95d3adafc8..798713ef59 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -11,6 +11,7 @@ #include "event_data.h" #include "data.h" #include "item.h" +#include "move.h" #include "pokemon.h" #include "random.h" #include "recorded_battle.h" @@ -22,16 +23,6 @@ #include "constants/moves.h" #include "constants/items.h" -#define CHECK_MOVE_FLAG(flag) \ - s32 i; \ - u16 *moves = GetMovesArray(battler); \ - for (i = 0; i < MAX_MON_MOVES; i++) \ - { \ - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].flag) \ - return TRUE; \ - } \ - return FALSE - static u32 AI_GetEffectiveness(uq4_12_t multiplier); // Functions @@ -338,9 +329,10 @@ bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler) for (i = 0; i < MAX_MON_MOVES; i++) { u32 move = gBattleResources->battleHistory->usedMoves[opposingBattler][i]; - if (gMovesInfo[move].effect == EFFECT_PROTECT && move != MOVE_ENDURE) + u32 effect = GetMoveEffect(move); + if (effect == EFFECT_PROTECT && move != MOVE_ENDURE) return TRUE; - if (gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE && AI_IsSlower(battlerAI, opposingBattler, GetAIChosenMove(battlerAI))) + if (effect == EFFECT_SEMI_INVULNERABLE && AI_IsSlower(battlerAI, opposingBattler, GetAIChosenMove(battlerAI))) return TRUE; } return FALSE; @@ -373,7 +365,7 @@ bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, u32 category) && !(unusable & (1u << i))) { SetTypeBeforeUsingMove(moves[i], attacker); - moveType = GetMoveType(moves[i]); + moveType = GetBattleMoveType(moves[i]); if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, AI_DATA->abilities[target], FALSE) != 0) usable |= 1u << i; } @@ -450,7 +442,7 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy if (CanAbilityAbsorbMove(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, moveType)) return TRUE; - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_DREAM_EATER: if (!AI_IsBattlerAsleepOrComatose(battlerDef)) @@ -470,11 +462,11 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy return TRUE; break; case EFFECT_FAIL_IF_NOT_ARG_TYPE: - if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[move].argument)) + if (!IS_BATTLER_OF_TYPE(battlerAtk, GetMoveArgType(move))) return TRUE; break; case EFFECT_HIT_SET_REMOVE_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && gMovesInfo[move].argument == ARG_TRY_REMOVE_TERRAIN_FAIL) + if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && GetMoveEffectArg_MoveProperty(move) == ARG_TRY_REMOVE_TERRAIN_FAIL) return TRUE; break; case EFFECT_POLTERGEIST: @@ -512,7 +504,7 @@ static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType) static inline void SetMoveDamageCategory(u32 battlerAtk, u32 battlerDef, u32 move) { - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_PHOTON_GEYSER: gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL); @@ -535,14 +527,14 @@ static inline void SetMoveDamageCategory(u32 battlerAtk, u32 battlerDef, u32 mov static inline s32 SetFixedMoveBasePower(u32 battlerAtk, u32 move) { s32 fixedBasePower = 0, n = 0; - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_ROLLOUT: n = gDisableStructs[battlerAtk].rolloutTimer - 1; - fixedBasePower = CalcRolloutBasePower(battlerAtk, gMovesInfo[move].power, n < 0 ? 5 : n); + fixedBasePower = CalcRolloutBasePower(battlerAtk, GetMovePower(move), n < 0 ? 5 : n); break; case EFFECT_FURY_CUTTER: - fixedBasePower = CalcFuryCutterBasePower(gMovesInfo[move].power, min(gDisableStructs[battlerAtk].furyCutterCounter + 1, 5)); + fixedBasePower = CalcFuryCutterBasePower(GetMovePower(move), min(gDisableStructs[battlerAtk].furyCutterCounter + 1, 5)); break; default: fixedBasePower = 0; @@ -554,10 +546,11 @@ static inline s32 SetFixedMoveBasePower(u32 battlerAtk, u32 move) static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCalcData, s32 *expectedDamage, s32 *minimumDamage, u32 holdEffectAtk, u32 abilityAtk) { u32 move = damageCalcData->move; + u32 effect = GetMoveEffect(move); s32 expected = *expectedDamage; s32 minimum = *minimumDamage; - switch (gMovesInfo[move].effect) + switch (effect) { case EFFECT_LEVEL_DAMAGE: expected = minimum = gBattleMons[damageCalcData->battlerAtk].level * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1); @@ -566,7 +559,7 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal expected = minimum = gBattleMons[damageCalcData->battlerAtk].level * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1); break; case EFFECT_FIXED_DAMAGE_ARG: - expected = minimum = gMovesInfo[move].argument * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1); + expected = minimum = GetMoveFixedDamage(move) * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1); break; case EFFECT_MULTI_HIT: if (move == MOVE_WATER_SHURIKEN && gBattleMons[damageCalcData->battlerAtk].species == SPECIES_GRENINJA_ASH) @@ -620,10 +613,11 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal } // Handle other multi-strike moves - if (gMovesInfo[move].strikeCount > 1 && gMovesInfo[move].effect != EFFECT_TRIPLE_KICK) + u32 strikeCount = GetMoveStrikeCount(move); + if (strikeCount > 1 && effect != EFFECT_TRIPLE_KICK) { - expected *= gMovesInfo[move].strikeCount; - minimum *= gMovesInfo[move].strikeCount; + expected *= strikeCount; + minimum *= strikeCount; } if (expected == 0) @@ -639,7 +633,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u { struct SimulatedDamage simDamage; s32 moveType; - u32 moveEffect = gMovesInfo[move].effect; + u32 moveEffect = GetMoveEffect(move); uq4_12_t effectivenessMultiplier; bool32 isDamageMoveUnusable = FALSE; bool32 toggledGimmick = FALSE; @@ -663,13 +657,14 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u SetMoveDamageCategory(battlerAtk, battlerDef, move); SetTypeBeforeUsingMove(move, battlerAtk); - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); effectivenessMultiplier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, aiData->abilities[battlerDef], FALSE); - if (gMovesInfo[move].power) + u32 movePower = GetMovePower(move); + if (movePower) isDamageMoveUnusable = IsDamageMoveUnusable(battlerAtk, battlerDef, move, moveType); - if (gMovesInfo[move].power && !isDamageMoveUnusable) + if (movePower && !isDamageMoveUnusable) { s32 critChanceIndex, fixedBasePower; @@ -723,7 +718,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u s32 nonCritDmg = 0; if (moveEffect == EFFECT_TRIPLE_KICK) { - for (gMultiHitCounter = gMovesInfo[move].strikeCount; gMultiHitCounter > 0; gMultiHitCounter--) // The global is used to simulate actual damage done + for (gMultiHitCounter = GetMoveStrikeCount(move); gMultiHitCounter > 0; gMultiHitCounter--) // The global is used to simulate actual damage done { nonCritDmg += CalculateMoveDamageVars(&damageCalcData, fixedBasePower, effectivenessMultiplier, weather, @@ -785,7 +780,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 u32 abilityDef = AI_DATA->abilities[battlerDef]; u32 abilityAtk = AI_DATA->abilities[battlerAtk]; - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_HIT_ESCAPE: if (CountUsablePartyMons(battlerAtk) != 0 && ShouldPivot(battlerAtk, battlerDef, abilityDef, move, AI_THINKING_STRUCT->movesetIndex)) @@ -798,12 +793,14 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 } // check ADDITIONAL_EFFECTS - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + for (i = 0; i < additionalEffectCount; i++) { + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); // Consider move effects that target self - if (gMovesInfo[move].additionalEffects[i].self) + if (additionalEffect->self) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_ATK_PLUS_2: @@ -846,7 +843,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 } else // consider move effects that hinder the target { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_POISON: case MOVE_EFFECT_TOXIC: @@ -880,7 +877,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 case MOVE_EFFECT_SP_DEF_MINUS_1: case MOVE_EFFECT_ACC_MINUS_1: case MOVE_EFFECT_EVS_MINUS_1: - if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1) + if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1) return TRUE; break; case MOVE_EFFECT_ATK_MINUS_2: @@ -890,7 +887,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 case MOVE_EFFECT_SP_DEF_MINUS_2: case MOVE_EFFECT_ACC_MINUS_2: case MOVE_EFFECT_EVS_MINUS_2: - if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1) + if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1) return TRUE; break; } @@ -907,10 +904,10 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s u8 i; // recoil - if (gMovesInfo[move].recoil > 0 && AI_IsDamagedByRecoil(battlerAtk)) + if (GetMoveRecoil(move) > 0 && AI_IsDamagedByRecoil(battlerAtk)) return TRUE; - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_MAX_HP_50_RECOIL: case EFFECT_MIND_BLOWN: @@ -923,9 +920,11 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s break; default: { - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + for (i = 0; i < additionalEffectCount; i++) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + switch (additionalEffect->moveEffect) { case MOVE_EFFECT_ATK_MINUS_1: case MOVE_EFFECT_DEF_MINUS_1: @@ -944,12 +943,12 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s case MOVE_EFFECT_V_CREATE: case MOVE_EFFECT_ATK_DEF_DOWN: case MOVE_EFFECT_DEF_SPDEF_DOWN: - if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk != ABILITY_CONTRARY) + if ((additionalEffect->self && abilityAtk != ABILITY_CONTRARY) || (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move))) return TRUE; break; case MOVE_EFFECT_RECHARGE: - return gMovesInfo[move].additionalEffects[i].self; + return additionalEffect->self; case MOVE_EFFECT_ATK_PLUS_1: case MOVE_EFFECT_DEF_PLUS_1: case MOVE_EFFECT_SPD_PLUS_1: @@ -965,7 +964,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s case MOVE_EFFECT_EVS_PLUS_2: case MOVE_EFFECT_ACC_PLUS_2: case MOVE_EFFECT_ALL_STATS_UP: - if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk == ABILITY_CONTRARY) + if ((additionalEffect->self && abilityAtk == ABILITY_CONTRARY) || (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move)))) return TRUE; break; @@ -989,9 +988,11 @@ s32 AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_ROCKY_HELMET || defAbility == ABILITY_IRON_BARBS || defAbility == ABILITY_ROUGH_SKIN)) { - if (gMovesInfo[move1].makesContact && !gMovesInfo[move2].makesContact) + bool32 moveContact1 = MoveMakesContact(move1); + bool32 moveContact2 = MoveMakesContact(move2); + if (moveContact1 && !moveContact2) return -1; - if (gMovesInfo[move2].makesContact && !gMovesInfo[move1].makesContact) + if (moveContact2 && !moveContact1) return 1; } @@ -1050,7 +1051,7 @@ uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef) gBattleStruct->dynamicMoveType = 0; SetTypeBeforeUsingMove(move, battlerAtk); - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], FALSE); RestoreBattlerData(battlerAtk); @@ -1102,7 +1103,7 @@ s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler, u32 moveConsidered) u32 abilityAI = AI_DATA->abilities[battlerAI]; u32 abilityPlayer = AI_DATA->abilities[battler]; - if (GetMovePriority(battlerAI, moveConsidered) > 0) + if (GetBattleMovePriority(battlerAI, moveConsidered) > 0) return AI_IS_FASTER; speedBattlerAI = GetBattlerTotalSpeedStatArgs(battlerAI, abilityAI, holdEffectAI); @@ -1142,9 +1143,10 @@ s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler, u32 moveConsidered) static bool32 CanEndureHit(u32 battler, u32 battlerTarget, u32 move) { - if (!AI_BattlerAtMaxHp(battlerTarget) || gMovesInfo[move].effect == EFFECT_MULTI_HIT) + u32 effect = GetMoveEffect(move); + if (!AI_BattlerAtMaxHp(battlerTarget) || effect == EFFECT_MULTI_HIT) return FALSE; - if (gMovesInfo[move].strikeCount > 1 && !(gMovesInfo[move].effect == EFFECT_DRAGON_DARTS && IsValidDoubleBattle(battlerTarget))) + if (GetMoveStrikeCount(move) > 1 && !(effect == EFFECT_DRAGON_DARTS && IsValidDoubleBattle(battlerTarget))) return FALSE; if (AI_DATA->holdEffects[battlerTarget] == HOLD_EFFECT_FOCUS_SASH) return TRUE; @@ -1409,7 +1411,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move) if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return FALSE; // AI handicap flag: doesn't understand ability suppression concept - if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || gMovesInfo[move].ignoresTargetAbility) + if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || MoveIgnoresTargetAbility(move)) return TRUE; return FALSE; @@ -1510,11 +1512,11 @@ bool32 IsSemiInvulnerable(u32 battlerDef, u32 move) return TRUE; else if (gBattleStruct->commandingDondozo & (1u << battlerDef)) return TRUE; - else if (!gMovesInfo[move].damagesAirborne && gStatuses3[battlerDef] & STATUS3_ON_AIR) + else if (!MoveDamagesAirborne(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR) return TRUE; - else if (!gMovesInfo[move].damagesUnderwater && gStatuses3[battlerDef] & STATUS3_UNDERWATER) + else if (!MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER) return TRUE; - else if (!gMovesInfo[move].damagesUnderground && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) + else if (!MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) return TRUE; else return FALSE; @@ -1535,22 +1537,23 @@ bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move) if (AI_DATA->abilities[battlerDef] == ABILITY_NO_GUARD || AI_DATA->abilities[battlerAtk] == ABILITY_NO_GUARD) return TRUE; - if (B_TOXIC_NEVER_MISS >= GEN_6 && gMovesInfo[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) + u32 effect = GetMoveEffect(move); + if (B_TOXIC_NEVER_MISS >= GEN_6 && effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) return TRUE; // discouraged from hitting weather = AI_GetWeather(AI_DATA); - if ((weather & B_WEATHER_SUN) && gMovesInfo[move].effect == EFFECT_THUNDER) + if ((weather & B_WEATHER_SUN) && effect == EFFECT_THUNDER) return FALSE; // increased accuracy but don't always hit - if ((weather & B_WEATHER_RAIN) && gMovesInfo[move].effect == EFFECT_THUNDER) + if ((weather & B_WEATHER_RAIN) && effect == EFFECT_THUNDER) return TRUE; - if ((weather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && gMovesInfo[move].effect == EFFECT_BLIZZARD) + if ((weather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && effect == EFFECT_BLIZZARD) return TRUE; - if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && gMovesInfo[move].minimizeDoubleDamage) + if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && MoveIncreasesPowerToMinimizedTargets(move)) return TRUE; - if (gMovesInfo[move].accuracy == 0) + if (GetMoveAccuracy(move) == 0) return TRUE; return FALSE; @@ -1712,7 +1715,7 @@ void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, if (uses == 0) { - if (predictedMove != MOVE_NONE && predictedMove != 0xFFFF && !IS_MOVE_STATUS(predictedMove)) + if (predictedMove != MOVE_NONE && predictedMove != 0xFFFF && !IsBattleMoveStatus(predictedMove)) ADJUST_SCORE_PTR(DECENT_EFFECT); else if (Random() % 256 < 100) ADJUST_SCORE_PTR(WEAK_EFFECT); @@ -1976,7 +1979,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv for (i = 0; i < MAX_MON_MOVES; i++) { - if (onlyOffensive && IS_MOVE_STATUS(moves[i])) + if (onlyOffensive && IsBattleMoveStatus(moves[i])) continue; if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetBattleMoveCategory(moves[i]) != category) return FALSE; @@ -2005,7 +2008,7 @@ bool32 HasMoveWithType(u32 battler, u32 type) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].type == type) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMoveType(moves[i]) == type) return TRUE; } @@ -2020,14 +2023,14 @@ bool32 HasMoveEffect(u32 battlerId, u32 effect) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && gMovesInfo[moves[i]].effect == effect) + && GetMoveEffect(moves[i]) == effect) return TRUE; } return FALSE; } -bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument) +bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument) { s32 i; u16 *moves = GetMovesArray(battlerId); @@ -2035,8 +2038,8 @@ bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && gMovesInfo[moves[i]].effect == effect - && (gMovesInfo[moves[i]].argument & argument)) + && GetMoveEffect(moves[i]) == effect + && (GetMoveEffectArg_Status(moves[i]) & argument)) return TRUE; } @@ -2066,7 +2069,7 @@ bool32 HasMoveWithCriticalHitChance(u32 battlerId) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && gMovesInfo[moves[i]].criticalHitStage > 0) + && GetMoveCriticalHitStage(moves[i]) > 0) return TRUE; } @@ -2081,7 +2084,7 @@ bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && gMovesInfo[moves[i]].effect != exception + && GetMoveEffect(moves[i]) != exception && MoveHasAdditionalEffect(moves[i], moveEffect)) return TRUE; } @@ -2127,9 +2130,11 @@ bool32 HasMoveThatLowersOwnStats(u32 battlerId) aiMove = moves[i]; if (aiMove != MOVE_NONE && aiMove != MOVE_UNAVAILABLE) { - for (j = 0; j < gMovesInfo[aiMove].numAdditionalEffects; j++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(aiMove); + for (j = 0; j < additionalEffectCount; j++) { - if (IsSelfStatLoweringEffect(gMovesInfo[aiMove].additionalEffects[j].moveEffect) && gMovesInfo[aiMove].additionalEffects[j].self) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(aiMove, j); + if (IsSelfStatLoweringEffect(additionalEffect->moveEffect) && additionalEffect->self) return TRUE; } } @@ -2150,9 +2155,9 @@ bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool if (!((1u << i) & moveLimitations)) { - if (ignoreStatus && IS_MOVE_STATUS(moves[i])) + if (ignoreStatus && IsBattleMoveStatus(moves[i])) continue; - else if ((!IS_MOVE_STATUS(moves[i]) && gMovesInfo[moves[i]].accuracy == 0) + else if ((!IsBattleMoveStatus(moves[i]) && GetMoveAccuracy(moves[i]) == 0) || GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD)) continue; @@ -2176,7 +2181,7 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef) break; if (!((1u << i) & moveLimitations)) { - if (gMovesInfo[moves[i]].effect == EFFECT_SLEEP + if (GetMoveEffect(moves[i]) == EFFECT_SLEEP && AI_DATA->moveAccuracy[battlerAtk][battlerDef][i] < 85) return TRUE; } @@ -2184,11 +2189,6 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef) return FALSE; } -bool32 IsHealingMove(u32 move) -{ - return gMovesInfo[move].healingMove; -} - bool32 HasHealingEffect(u32 battlerId) { s32 i; @@ -2205,7 +2205,7 @@ bool32 HasHealingEffect(u32 battlerId) bool32 IsTrappingMove(u32 move) { - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_MEAN_LOOK: case EFFECT_FAIRY_LOCK: @@ -2233,7 +2233,14 @@ bool32 HasTrappingMoveEffect(u32 battler) bool32 HasThawingMove(u32 battler) { - CHECK_MOVE_FLAG(thawsUser); + s32 i; + u16 *moves = GetMovesArray(battler); + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveThawsUser(moves[i])) + return TRUE; + } + return FALSE; } bool32 IsUngroundingEffect(u32 effect) @@ -2388,7 +2395,7 @@ bool32 IsSwitchOutEffect(u32 effect) static inline bool32 IsMoveSleepClauseTrigger(u32 move) { - u32 i, effect = gMovesInfo[move].effect; + u32 i, effect = GetMoveEffect(move); // Sleeping effects like Sleep Powder, Yawn, Dark Void, etc. switch (effect) @@ -2400,9 +2407,11 @@ static inline bool32 IsMoveSleepClauseTrigger(u32 move) } // Sleeping effects like G-Max Befuddle, G-Max Snooze, etc. - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + for (i = 0; i < additionalEffectCount; i++) { - switch (gMovesInfo[move].additionalEffects[i].moveEffect) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + switch (additionalEffect->moveEffect) { case MAX_EFFECT_EFFECT_SPORE_FOES: case MAX_EFFECT_YAWN_FOE: @@ -2419,7 +2428,7 @@ bool32 HasDamagingMove(u32 battlerId) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !IS_MOVE_STATUS(moves[i])) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !IsBattleMoveStatus(moves[i])) return TRUE; } @@ -2434,7 +2443,7 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && !IS_MOVE_STATUS(moves[i]].type == type && gMovesInfo[moves[i])) + && GetMoveType(moves[i]) == type && !IsBattleMoveStatus(moves[i])) return TRUE; } @@ -2443,7 +2452,14 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type) bool32 HasSubstituteIgnoringMove(u32 battler) { - CHECK_MOVE_FLAG(ignoresSubstitute); + s32 i; + u16 *moves = GetMovesArray(battler); + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveIgnoresSubstitute(moves[i])) + return TRUE; + } + return FALSE; } bool32 HasHighCritRatioMove(u32 battler) @@ -2453,7 +2469,7 @@ bool32 HasHighCritRatioMove(u32 battler) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].criticalHitStage > 0) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMoveCriticalHitStage(moves[i]) > 0) return TRUE; } @@ -2462,22 +2478,36 @@ bool32 HasHighCritRatioMove(u32 battler) bool32 HasMagicCoatAffectedMove(u32 battler) { - CHECK_MOVE_FLAG(magicCoatAffected); + s32 i; + u16 *moves = GetMovesArray(battler); + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveCanBeBouncedBack(moves[i])) + return TRUE; + } + return FALSE; } bool32 HasSnatchAffectedMove(u32 battler) { - CHECK_MOVE_FLAG(snatchAffected); + s32 i; + u16 *moves = GetMovesArray(battler); + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveCanBeSnatched(moves[i])) + return TRUE; + } + return FALSE; } bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move) { - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_SOLAR_BEAM: case EFFECT_TWO_TURNS_ATTACK: return !(AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB - || (AI_GetWeather(AI_DATA) & gMovesInfo[move].argument)); + || (AI_GetWeather(AI_DATA) & GetMoveTwoTurnAttackWeather(move))); default: return FALSE; } @@ -2714,7 +2744,7 @@ static bool32 PartyBattlerShouldAvoidHazards(u32 currBattler, u32 switchBattler) return FALSE; if (flags & SIDE_STATUS_STEALTH_ROCK) - hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_STEALTH_ROCK].type, type1, type2, maxHp); + hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), type1, type2, maxHp); if (flags & SIDE_STATUS_SPIKES && ((type1 != TYPE_FLYING && type2 != TYPE_FLYING && ability != ABILITY_LEVITATE && holdEffect != HOLD_EFFECT_AIR_BALLOON) @@ -2760,7 +2790,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov if (CanTargetFaintAi(battlerDef, battlerAtk)) return SHOULD_PIVOT; // Won't get the two turns, pivot - if (!IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) + if (!IsBattleMoveStatus(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) || (AI_BattlerAtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH || (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY) || defAbility == ABILITY_MULTISCALE @@ -2769,7 +2799,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov } else if (!hasStatBoost) { - if (!IS_MOVE_STATUS(move) && (AI_BattlerAtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH + if (!IsBattleMoveStatus(move) && (AI_BattlerAtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH || (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY) || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD))) @@ -2816,7 +2846,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov { if (CanTargetFaintAi(battlerDef, battlerAtk)) { - if (gMovesInfo[move].effect == EFFECT_TELEPORT) + if (GetMoveEffect(move) == EFFECT_TELEPORT) return DONT_PIVOT; // If you're going to faint because you'll go second, use a different move else return CAN_TRY_PIVOT; // You're probably going to faint anyways so if for some reason you don't, better switch @@ -2846,7 +2876,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov else if (CanAIFaintTarget(battlerAtk, battlerDef, 2)) { // can knock out foe in 2 hits - if (IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) //Damaging move + if (IsBattleMoveStatus(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) //Damaging move //&& (switchScore >= SWITCHING_INCREASE_RESIST_ALL_MOVES + SWITCHING_INCREASE_KO_FOE //remove hazards || (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH && AI_BattlerAtMaxHp(battlerDef)))) return DONT_PIVOT; // Pivot to break the sash @@ -3002,7 +3032,7 @@ bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability) bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove) { - if (gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY + if (GetBattlerMoveTargetType(battlerAtk, move) == MOVE_TARGET_FOES_AND_ALLY && AI_CanBeConfused(battlerAtk, battlerDef, move, defAbility) && !AI_CanBeConfused(battlerAtk, BATTLE_PARTNER(battlerDef), move, AI_DATA->abilities[BATTLE_PARTNER(battlerDef)])) return FALSE; @@ -3229,8 +3259,7 @@ bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage) if (move == 0xFFFF || AI_IsFaster(battlerAtk, battlerDef, move)) { // using item or user goes first - u32 healPercent = (gMovesInfo[move].argument == 0) ? 50 : gMovesInfo[move].argument; - s32 healDmg = (healPercent * damage) / 100; + s32 healDmg = (GetMoveAbsorbPercentage(move) * damage) / 100; if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) healDmg = 0; @@ -3331,7 +3360,7 @@ bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32 if (!IsDoubleBattle()) return FALSE; - if (gMovesInfo[move].effect == gMovesInfo[partnerMove].effect + if (GetMoveEffect(move) == GetMoveEffect(partnerMove) && partnerMove != MOVE_NONE && gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef) { @@ -3346,7 +3375,7 @@ bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u3 if (!IsDoubleBattle()) return FALSE; - if (gMovesInfo[move].effect == gMovesInfo[partnerMove].effect + if (GetMoveEffect(move) == GetMoveEffect(partnerMove) && partnerMove != MOVE_NONE) return TRUE; return FALSE; @@ -3358,27 +3387,29 @@ bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef if (!IsDoubleBattle()) return FALSE; + u32 partnerEffect = GetMoveEffect(partnerMove); if (partnerMove != MOVE_NONE && gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef - && (gMovesInfo[partnerMove].effect == EFFECT_SLEEP - || gMovesInfo[partnerMove].effect == EFFECT_POISON - || gMovesInfo[partnerMove].effect == EFFECT_TOXIC - || gMovesInfo[partnerMove].effect == EFFECT_PARALYZE - || gMovesInfo[partnerMove].effect == EFFECT_WILL_O_WISP - || gMovesInfo[partnerMove].effect == EFFECT_YAWN)) + && (partnerEffect == EFFECT_SLEEP + || partnerEffect == EFFECT_POISON + || partnerEffect == EFFECT_TOXIC + || partnerEffect == EFFECT_PARALYZE + || partnerEffect == EFFECT_WILL_O_WISP + || partnerEffect == EFFECT_YAWN)) return TRUE; return FALSE; } bool32 IsMoveEffectWeather(u32 move) { + u32 effect = GetMoveEffect(move); if (move != MOVE_NONE - && (gMovesInfo[move].effect == EFFECT_SUNNY_DAY - || gMovesInfo[move].effect == EFFECT_RAIN_DANCE - || gMovesInfo[move].effect == EFFECT_SANDSTORM - || gMovesInfo[move].effect == EFFECT_HAIL - || gMovesInfo[move].effect == EFFECT_SNOWSCAPE - || gMovesInfo[move].effect == EFFECT_CHILLY_RECEPTION)) + && (effect == EFFECT_SUNNY_DAY + || effect == EFFECT_RAIN_DANCE + || effect == EFFECT_SANDSTORM + || effect == EFFECT_HAIL + || effect == EFFECT_SNOWSCAPE + || effect == EFFECT_CHILLY_RECEPTION)) return TRUE; return FALSE; } @@ -3389,11 +3420,12 @@ bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove) if (!IsDoubleBattle()) return FALSE; + u32 partnerEffect = GetMoveEffect(partnerMove); if (partnerMove != MOVE_NONE - && (gMovesInfo[partnerMove].effect == EFFECT_GRASSY_TERRAIN - || gMovesInfo[partnerMove].effect == EFFECT_MISTY_TERRAIN - || gMovesInfo[partnerMove].effect == EFFECT_ELECTRIC_TERRAIN - || gMovesInfo[partnerMove].effect == EFFECT_PSYCHIC_TERRAIN)) + && (partnerEffect == EFFECT_GRASSY_TERRAIN + || partnerEffect == EFFECT_MISTY_TERRAIN + || partnerEffect == EFFECT_ELECTRIC_TERRAIN + || partnerEffect == EFFECT_PSYCHIC_TERRAIN)) return TRUE; return FALSE; @@ -3443,7 +3475,7 @@ bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move) u32 i; s32 firstId, lastId; struct Pokemon* party; - bool32 hasStatus = AnyPartyMemberStatused(battlerAtk, gMovesInfo[move].soundMove); + bool32 hasStatus = AnyPartyMemberStatused(battlerAtk, IsSoundMove(move)); bool32 needHealing = FALSE; GetAIPartyIndexes(battlerAtk, &firstId, &lastId); @@ -3470,7 +3502,7 @@ bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move) if (!IsDoubleBattle()) { - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_WISH: if (needHealing) @@ -3483,7 +3515,7 @@ bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move) } else { - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_WISH: return ShouldRecover(battlerAtk, battlerDef, move, 50); // Switch recovery isn't good idea in doubles @@ -3626,7 +3658,7 @@ bool32 PartyHasMoveCategory(u32 battlerId, u32 category) if (pp > 0 && move != MOVE_NONE) { //TODO - handle photon geyser, light that burns the sky - if (gMovesInfo[move].category == category) + if (GetMoveCategory(move) == category) return TRUE; } } @@ -3847,7 +3879,7 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT)) ADJUST_SCORE_PTR(WEAK_EFFECT); // stall tactic - if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY) + if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY) || HasMoveEffect(battlerAtk, EFFECT_VENOM_DRENCH) || AI_DATA->abilities[battlerAtk] == ABILITY_MERCILESS) ADJUST_SCORE_PTR(DECENT_EFFECT); @@ -3868,14 +3900,14 @@ void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) || (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects physical attacker && gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack + 10)) { - if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].category == DAMAGE_CATEGORY_PHYSICAL) + if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk)) == DAMAGE_CATEGORY_PHYSICAL) ADJUST_SCORE_PTR(DECENT_EFFECT); else ADJUST_SCORE_PTR(WEAK_EFFECT); } - if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN) - || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)) + if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN) + || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)) ADJUST_SCORE_PTR(WEAK_EFFECT); } } @@ -3892,7 +3924,7 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) u32 defSpeed = AI_DATA->speedStats[battlerDef]; if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe - || HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS) + || IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS) || (HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)) // filter out Fake Out || gBattleMons[battlerDef].status2 & STATUS2_INFATUATION || gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) @@ -3917,8 +3949,8 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) && !(HasMoveEffect(battlerDef, EFFECT_SNORE) || HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK))) ADJUST_SCORE_PTR(WEAK_EFFECT); - if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP) - || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)) + if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP) + || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)) ADJUST_SCORE_PTR(WEAK_EFFECT); } @@ -3952,21 +3984,21 @@ void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score || (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects special attacker && gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack + 10)) { - if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].category == DAMAGE_CATEGORY_SPECIAL) + if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk)) == DAMAGE_CATEGORY_SPECIAL) ADJUST_SCORE_PTR(DECENT_EFFECT); else ADJUST_SCORE_PTR(WEAK_EFFECT); } - if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE) - || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)) + if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE) + || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)) ADJUST_SCORE_PTR(WEAK_EFFECT); } } bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move) { - if (gMovesInfo[move].makesContact + if (MoveMakesContact(move) && ability != ABILITY_LONG_REACH && holdEffect != HOLD_EFFECT_PROTECTIVE_PADS) return TRUE; @@ -3989,22 +4021,22 @@ bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove) struct SimulatedDamage dmg; if (gBattleMons[battlerDef].ability == ABILITY_DISGUISE - && !gMovesInfo[zMove].ignoresTargetAbility + && !MoveIgnoresTargetAbility(zMove) && (gBattleMons[battlerDef].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battlerDef].species == SPECIES_MIMIKYU_TOTEM_DISGUISED)) return FALSE; // Don't waste a Z-Move busting disguise if (gBattleMons[battlerDef].ability == ABILITY_ICE_FACE - && !gMovesInfo[zMove].ignoresTargetAbility - && gBattleMons[battlerDef].species == SPECIES_EISCUE_ICE && IS_MOVE_PHYSICAL(chosenMove)) + && !MoveIgnoresTargetAbility(zMove) + && gBattleMons[battlerDef].species == SPECIES_EISCUE_ICE && IsBattleMovePhysical(chosenMove)) return FALSE; // Don't waste a Z-Move busting Ice Face - if (IS_MOVE_STATUS(chosenMove) && !IS_MOVE_STATUS(zMove)) + if (IsBattleMoveStatus(chosenMove) && !IsBattleMoveStatus(zMove)) return FALSE; - else if (!IS_MOVE_STATUS(chosenMove) && IS_MOVE_STATUS(zMove)) + else if (!IsBattleMoveStatus(chosenMove) && IsBattleMoveStatus(zMove)) return FALSE; dmg = AI_CalcDamageSaveBattlers(chosenMove, battlerAtk, battlerDef, &effectiveness, FALSE, DMG_ROLL_DEFAULT); - if (!IS_MOVE_STATUS(chosenMove) && dmg.minimum >= gBattleMons[battlerDef].hp) + if (!IsBattleMoveStatus(chosenMove) && dmg.minimum >= gBattleMons[battlerDef].hp) return FALSE; // don't waste damaging z move if can otherwise faint target return TRUE; @@ -4107,7 +4139,7 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st || partnerAbility == ABILITY_WHITE_SMOKE || partnerHoldEffect == HOLD_EFFECT_CLEAR_AMULET); - switch (gMovesInfo[aiData->partnerMove].effect) + switch (GetMoveEffect(aiData->partnerMove)) { case EFFECT_DEFENSE_UP: case EFFECT_DEFENSE_UP_2: @@ -4125,12 +4157,13 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (gMovesInfo[move].effect == EFFECT_SUBSTITUTE) // Substitute specific + u32 effect = GetMoveEffect(move); + if (effect == EFFECT_SUBSTITUTE) // Substitute specific { if (HasAnyKnownMove(battlerDef) && GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 4) ADJUST_SCORE_PTR(GOOD_EFFECT); } - else if (gMovesInfo[move].effect == EFFECT_SHED_TAIL) // Shed Tail specific + else if (effect == EFFECT_SHED_TAIL) // Shed Tail specific { if ((ShouldPivot(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_THINKING_STRUCT->movesetIndex)) && (HasAnyKnownMove(battlerDef) && (GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 2))) diff --git a/src/battle_anim.c b/src/battle_anim.c index b036f83cbf..3e079647d2 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -2230,7 +2230,7 @@ static void Cmd_jumpifmovetypeequal(void) { const u8 *type = sBattleAnimScriptPtr + 1; sBattleAnimScriptPtr += 2; - if (*type != GetMoveType(gCurrentMove)) + if (*type != GetBattleMoveType(gCurrentMove)) sBattleAnimScriptPtr += 4; else sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 826586cf9b..a3104122d1 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6736,6 +6736,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) SwapStructData(&gSpecialStatuses[battlerAtk], &gSpecialStatuses[battlerPartner], data, sizeof(struct SpecialStatus)); SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct)); SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo)); + SwapStructData(&gBattleStruct->illusion[battlerAtk], &gBattleStruct->illusion[battlerPartner], data, sizeof(struct Illusion)); SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp); SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp); diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index 50bb83305f..7308a9d6fd 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -4380,6 +4380,29 @@ const struct SpriteTemplate gSpriteTemplate_FlipTurnBack = { .callback = AnimAbsorptionOrb }; +// U-Turn +const struct SpriteTemplate gUTurnBallSpriteTemplate = +{ + .tileTag = ANIM_TAG_SMALL_BUBBLES, + .paletteTag = ANIM_TAG_RAZOR_LEAF, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAffineAnims_ShadowBall, + .callback = AnimShadowBall, +}; + +const struct SpriteTemplate gUTurnBallBackSpriteTemplate = +{ + .tileTag = ANIM_TAG_SMALL_BUBBLES, + .paletteTag = ANIM_TAG_RAZOR_LEAF, + .oam = &gOamData_AffineOff_ObjNormal_16x16, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gAffineAnims_ShadowBall, + .callback = AnimAbsorptionOrb, +}; + // wicked blow static const union AffineAnimCmd sSpriteAffineAnim_DrainPunchFist[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 1), //Double sprite size @@ -9244,19 +9267,19 @@ void AnimTask_DynamaxGrowth(u8 taskId) // from CFRU void AnimTask_GetWeatherToSet(u8 taskId) { - switch (gMovesInfo[gCurrentMove].argument) + switch (GetMoveMaxEffect(gCurrentMove)) { case MAX_EFFECT_SUN: - gBattleAnimArgs[ARG_RET_ID] = 1; + gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SUN; break; case MAX_EFFECT_RAIN: - gBattleAnimArgs[ARG_RET_ID] = 2; + gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_RAIN; break; case MAX_EFFECT_SANDSTORM: - gBattleAnimArgs[ARG_RET_ID] = 3; + gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM; break; case MAX_EFFECT_HAIL: - gBattleAnimArgs[ARG_RET_ID] = 4; + gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL; break; } DestroyAnimVisualTask(taskId); diff --git a/src/battle_arena.c b/src/battle_arena.c index 4a6df309b5..ff406a37df 100644 --- a/src/battle_arena.c +++ b/src/battle_arena.c @@ -362,18 +362,19 @@ void BattleArena_AddMindPoints(u8 battler) // - Fake Out subtracts 1 point // All status moves give 0 points, with the following exceptions: // - Protect, Detect, and Endure subtract 1 point + u32 effect = GetMoveEffect(gCurrentMove); - if (gMovesInfo[gCurrentMove].effect == EFFECT_FIRST_TURN_ONLY - || gMovesInfo[gCurrentMove].effect == EFFECT_PROTECT - || gMovesInfo[gCurrentMove].effect == EFFECT_ENDURE) + if (effect == EFFECT_FIRST_TURN_ONLY + || effect == EFFECT_PROTECT + || effect == EFFECT_ENDURE) { gBattleStruct->arenaMindPoints[battler]--; } - else if (!IS_MOVE_STATUS(gCurrentMove) - && gMovesInfo[gCurrentMove].effect != EFFECT_COUNTER - && gMovesInfo[gCurrentMove].effect != EFFECT_MIRROR_COAT - && gMovesInfo[gCurrentMove].effect != EFFECT_METAL_BURST - && gMovesInfo[gCurrentMove].effect != EFFECT_BIDE) + else if (!IsBattleMoveStatus(gCurrentMove) + && effect != EFFECT_COUNTER + && effect != EFFECT_MIRROR_COAT + && effect != EFFECT_METAL_BURST + && effect != EFFECT_BIDE) { gBattleStruct->arenaMindPoints[battler]++; } diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 2fbf8cf69f..898a59c2ee 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -609,7 +609,7 @@ static void OpponentHandleChooseMove(u32 battler) } while (!CanTargetBattler(battler, target, move)); // Don't bother to loop through table if the move can't attack ally - if (B_WILD_NATURAL_ENEMIES == TRUE && !(gMovesInfo[move].target & MOVE_TARGET_BOTH)) + if (B_WILD_NATURAL_ENEMIES == TRUE && !(GetBattlerMoveTargetType(battler, move) & MOVE_TARGET_BOTH)) { u16 i, speciesAttacker, speciesTarget, isPartnerEnemy = FALSE; static const u16 naturalEnemies[][2] = diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 00e73735e8..1eac4dbe26 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -680,13 +680,13 @@ void HandleInputChooseMove(u32 battler) if (gBattleStruct->zmove.viewing) { gBattleStruct->zmove.viewing = FALSE; - if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category != DAMAGE_CATEGORY_STATUS) + if (GetMoveCategory(moveInfo->moves[gMoveSelectionCursor[battler]]) != DAMAGE_CATEGORY_STATUS) moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target } // Status moves turn into Max Guard when Dynamaxed, targets user. if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX)) - moveTarget = gMovesInfo[GetMaxMove(battler, moveInfo->moves[gMoveSelectionCursor[battler]])].target; + moveTarget = GetMoveTarget(GetMaxMove(battler, moveInfo->moves[gMoveSelectionCursor[battler]])); if (moveTarget & MOVE_TARGET_USER) gMultiUsePlayerCursor = battler; @@ -1715,7 +1715,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) u32 speciesId; struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType); - type = gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].type; + type = GetMoveType(moveInfo->moves[gMoveSelectionCursor[battler]]); if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_BLAST) { @@ -1731,7 +1731,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) || speciesId == SPECIES_OGERPON_CORNERSTONE || speciesId == SPECIES_OGERPON_CORNERSTONE_TERA) type = gBattleMons[battler].types[1]; } - else if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category == DAMAGE_CATEGORY_STATUS + else if (GetMoveCategory(moveInfo->moves[gMoveSelectionCursor[battler]]) == DAMAGE_CATEGORY_STATUS && (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))) { type = TYPE_NORMAL; // Max Guard is always a Normal-type move @@ -1757,8 +1757,8 @@ static void MoveSelectionDisplayMoveDescription(u32 battler) { struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[battler][4]); u16 move = moveInfo->moves[gMoveSelectionCursor[battler]]; - u16 pwr = gMovesInfo[move].power; - u16 acc = gMovesInfo[move].accuracy; + u16 pwr = GetMovePower(move); + u16 acc = GetMoveAccuracy(move); u8 pwr_num[3], acc_num[3]; u8 cat_desc[7] = _("CAT: "); @@ -1786,10 +1786,7 @@ static void MoveSelectionDisplayMoveDescription(u32 battler) StringAppend(gDisplayedStringBattle, acc_desc); StringAppend(gDisplayedStringBattle, acc_num); StringAppend(gDisplayedStringBattle, gText_NewLine); - if (gMovesInfo[move].effect == EFFECT_PLACEHOLDER) - StringAppend(gDisplayedStringBattle, gNotDoneYetDescription); - else - StringAppend(gDisplayedStringBattle, gMovesInfo[move].description); + StringAppend(gDisplayedStringBattle, GetMoveDescription(move)); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_DESCRIPTION); if (gCategoryIconSpriteId == 0xFF) @@ -2050,8 +2047,9 @@ static void PlayerHandleChooseAction(u32 battler) { StringCopy(gStringVar1, COMPOUND_STRING("Partner will use:\n")); u32 move = gBattleMons[B_POSITION_PLAYER_RIGHT].moves[*(gBattleStruct->chosenMovePositions + B_POSITION_PLAYER_RIGHT)]; - StringAppend(gStringVar1, gMovesInfo[move].name); - if (gMovesInfo[move].target == MOVE_TARGET_SELECTED) + StringAppend(gStringVar1, GetMoveName(move)); + u32 moveTarget = GetBattlerMoveTargetType(B_POSITION_PLAYER_RIGHT, move); + if (moveTarget == MOVE_TARGET_SELECTED) { if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_LEFT) StringAppend(gStringVar1, COMPOUND_STRING(" -{UP_ARROW}")); @@ -2062,15 +2060,15 @@ static void PlayerHandleChooseAction(u32 battler) else if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_RIGHT) StringAppend(gStringVar1, COMPOUND_STRING(" {DOWN_ARROW}-")); } - else if (gMovesInfo[move].target == MOVE_TARGET_BOTH) + else if (moveTarget == MOVE_TARGET_BOTH) { StringAppend(gStringVar1, COMPOUND_STRING(" {UP_ARROW}{UP_ARROW}")); } - else if (gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY) + else if (moveTarget == MOVE_TARGET_FOES_AND_ALLY) { StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{UP_ARROW}")); } - else if (gMovesInfo[move].target == MOVE_TARGET_ALL_BATTLERS) + else if (moveTarget == MOVE_TARGET_ALL_BATTLERS) { StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{V_D_ARROW}")); } diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index f987c333ce..81170ec9de 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -353,10 +353,11 @@ static void PlayerPartnerHandleChooseMove(u32 battler) chosenMoveId = gBattleStruct->aiMoveOrAction[battler]; gBattlerTarget = gBattleStruct->aiChosenTarget[battler]; + u32 moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveId]); - if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) + if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) gBattlerTarget = battler; - else if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH) + else if (moveTarget & MOVE_TARGET_BOTH) { gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); if (gAbsentBattlerFlags & (1u << gBattlerTarget)) diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 553eb7a85c..d5a7290c63 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1113,7 +1113,7 @@ void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringID) stringInfo->bakScriptPartyIdx = gBattleStruct->scriptPartyIdx; stringInfo->hpScale = gBattleStruct->hpScale; stringInfo->itemEffectBattler = gPotentialItemEffectBattler; - stringInfo->moveType = gMovesInfo[gCurrentMove].type; + stringInfo->moveType = GetMoveType(gCurrentMove); for (i = 0; i < MAX_BATTLERS_COUNT; i++) stringInfo->abilities[i] = gBattleMons[i].ability; @@ -2542,7 +2542,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH; gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2; } - gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn; + else + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic; } diff --git a/src/battle_debug.c b/src/battle_debug.c index b03ef194f0..b0e1e23add 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1982,7 +1982,7 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_DAMAGE_NON_TYPES; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_DAMAGE_NON_TYPES; - sideTimer->damageNonTypesType = gMovesInfo[gCurrentMove].type; + sideTimer->damageNonTypesType = GetMoveType(gCurrentMove); } return &sideTimer->damageNonTypesTimer; case LIST_SIDE_RAINBOW: diff --git a/src/battle_dome.c b/src/battle_dome.c index 8b376c7e75..19c5086523 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -2395,13 +2395,13 @@ static int GetTypeEffectivenessPoints(int move, int targetSpecies, int mode) int defType1, defType2, defAbility, moveType; int typePower = TYPE_x1; - if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IS_MOVE_STATUS(move)) + if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IsBattleMoveStatus(move)) return 0; defType1 = gSpeciesInfo[targetSpecies].types[0]; defType2 = gSpeciesInfo[targetSpecies].types[1]; defAbility = gSpeciesInfo[targetSpecies].abilities[0]; - moveType = gMovesInfo[move].type; + moveType = GetMoveType(move); if (defAbility == ABILITY_LEVITATE && moveType == TYPE_GROUND) { @@ -3890,7 +3890,7 @@ static bool32 IsDomeHealingMove(u32 move) if (IsHealingMove(move)) return TRUE; // Check extra effects not considered plain healing by AI - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_INGRAIN: case EFFECT_REFRESH: @@ -3949,9 +3949,9 @@ static bool32 IsDomeRiskyMoveEffect(u32 effect) static bool32 IsDomeLuckyMove(u32 move) { - if (gMovesInfo[move].accuracy <= 50) + if (GetMoveAccuracy(move) <= 50) return TRUE; - switch(gMovesInfo[move].effect) + switch(GetMoveEffect(move)) { case EFFECT_COUNTER: case EFFECT_OHKO: // Technically redundant because of the above accuracy check @@ -3982,10 +3982,10 @@ static bool32 IsDomePopularMove(u32 move) if (i == NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES) return FALSE; // Filter in TMs/HMs - if (gMovesInfo[move].power >= 90) + if (GetMovePower(move) >= 90) return TRUE; - switch(gMovesInfo[move].effect) + switch(GetMoveEffect(move)) { case EFFECT_PROTECT: case EFFECT_MAT_BLOCK: @@ -4000,7 +4000,7 @@ static bool32 IsDomePopularMove(u32 move) static bool32 IsDomeStatusMoveEffect(u32 move) { - switch(gMovesInfo[move].effect) + switch(GetMoveEffect(move)) { case EFFECT_SLEEP: case EFFECT_CONFUSE: @@ -4294,24 +4294,26 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) { for (k = 0; k < NUM_MOVE_POINT_TYPES; k++) { - u16 move; + u32 move; if (trainerId == TRAINER_FRONTIER_BRAIN) move = GetFrontierBrainMonMove(i, j); else if (trainerId == TRAINER_PLAYER) move = gSaveBlock2Ptr->frontier.domePlayerPartyData[i].moves[j]; else move = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].moves[j]; + u32 effect = GetMoveEffect(move); + u32 accuracy = GetMoveAccuracy(move); switch (k) { case MOVE_POINTS_COMBO: - allocatedArray[k] = IsDomeComboMoveEffect(gMovesInfo[move].effect) ? 1 : 0; + allocatedArray[k] = IsDomeComboMoveEffect(effect) ? 1 : 0; break; case MOVE_POINTS_STAT_RAISE: - allocatedArray[k] = IsStatRaisingEffect(gMovesInfo[move].effect) ? 1 : 0; + allocatedArray[k] = IsStatRaisingEffect(effect) ? 1 : 0; break; case MOVE_POINTS_STAT_LOWER: - allocatedArray[k] = IsStatLoweringEffect(gMovesInfo[move].effect) ? 1 : 0; + allocatedArray[k] = IsStatLoweringEffect(effect) ? 1 : 0; break; case MOVE_POINTS_RARE: allocatedArray[k] = IsDomeRareMove(move) ? 1 : 0; @@ -4320,22 +4322,22 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) allocatedArray[k] = IsDomeHealingMove(move) ? 1 : 0; break; case MOVE_POINTS_RISKY: - allocatedArray[k] = IsDomeRiskyMoveEffect(gMovesInfo[move].effect) ? 1 : 0; + allocatedArray[k] = IsDomeRiskyMoveEffect(effect) ? 1 : 0; break; case MOVE_POINTS_STATUS: allocatedArray[k] = IsDomeStatusMoveEffect(move); break; case MOVE_POINTS_DMG: - allocatedArray[k] = (!IS_MOVE_STATUS(move)) ? 1 : 0; + allocatedArray[k] = (!IsBattleMoveStatus(move)) ? 1 : 0; break; case MOVE_POINTS_DEF: - allocatedArray[k] = IsDomeDefensiveMoveEffect(gMovesInfo[move].effect) ? 1 : 0; + allocatedArray[k] = IsDomeDefensiveMoveEffect(effect) ? 1 : 0; break; case MOVE_POINTS_ACCURATE: - allocatedArray[k] = (gMovesInfo[move].accuracy == 0 || gMovesInfo[move].accuracy == 100) ? 1 : 0; + allocatedArray[k] = (accuracy == 0 || accuracy == 100) ? 1 : 0; break; case MOVE_POINTS_POWERFUL: - allocatedArray[k] = (gMovesInfo[move].power >= 100) ? 1 : 0; + allocatedArray[k] = (GetMovePower(move) >= 100) ? 1 : 0; break; case MOVE_POINTS_POPULAR: allocatedArray[k] = IsDomePopularMove(move) ? 1 : 0; @@ -4344,10 +4346,10 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) allocatedArray[k] = IsDomeLuckyMove(move) ? 1 : 0; break; case MOVE_POINTS_STRONG: - allocatedArray[k] = (gMovesInfo[move].power >= 90) ? 1 : 0; + allocatedArray[k] = (GetMovePower(move) >= 90) ? 1 : 0; break; case MOVE_POINTS_LOW_PP: - allocatedArray[k] = (gMovesInfo[move].pp <= 5) ? 1 : 0; + allocatedArray[k] = (GetMovePP(move) <= 5) ? 1 : 0; break; case MOVE_POINTS_EFFECT: allocatedArray[k] = MoveIsAffectedBySheerForce(move); @@ -5107,12 +5109,12 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun else moveIds[i * MAX_MON_MOVES + j] = gFacilityTrainerMons[DOME_MONS[winnerTournamentId][i]].moves[j]; - movePower = gMovesInfo[moveIds[i * MAX_MON_MOVES + j]].power; - if (IS_MOVE_STATUS(moveIds[i * MAX_MON_MOVES + j])) + movePower = GetMovePower(moveIds[i * MAX_MON_MOVES + j]); + if (IsBattleMoveStatus(moveIds[i * MAX_MON_MOVES + j])) movePower = 40; else if (movePower == 1) movePower = 60; - else if (gMovesInfo[moveIds[i * MAX_MON_MOVES + j]].effect == EFFECT_EXPLOSION) + else if (GetMoveEffect(moveIds[i * MAX_MON_MOVES + j]) == EFFECT_EXPLOSION) movePower /= 2; for (k = 0; k < FRONTIER_PARTY_SIZE; k++) diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 98ee89af9b..c57151ac37 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -240,7 +240,7 @@ bool32 IsMoveBlockedByMaxGuard(u32 move) bool32 IsMoveBlockedByDynamax(u32 move) { // TODO: Certain moves are banned in raids. - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_HEAT_CRASH: case EFFECT_LOW_KICK: @@ -282,7 +282,7 @@ u16 GetMaxMove(u32 battler, u32 baseMove) { u32 moveType; SetTypeBeforeUsingMove(baseMove, battler); - moveType = GetMoveType(baseMove); + moveType = GetBattleMoveType(baseMove); if (baseMove == MOVE_NONE) // for move display { @@ -292,7 +292,7 @@ u16 GetMaxMove(u32 battler, u32 baseMove) { return MOVE_STRUGGLE; } - else if (gMovesInfo[baseMove].category == DAMAGE_CATEGORY_STATUS) + else if (GetMoveCategory(baseMove) == DAMAGE_CATEGORY_STATUS) { return MOVE_MAX_GUARD; } @@ -320,7 +320,7 @@ u8 GetMaxMovePower(u32 move) { u8 tier; // G-Max Drum Solo, G-Max Hydrosnipe, and G-Max Fireball always have 160 base power. - if (gMovesInfo[GetMaxMove(gBattlerAttacker, move)].argument == MAX_EFFECT_FIXED_POWER) + if (GetMoveMaxEffect(GetMaxMove(gBattlerAttacker, move)) == MAX_EFFECT_FIXED_POWER) return 160; // Exceptions to all other rules below: @@ -333,8 +333,9 @@ u8 GetMaxMovePower(u32 move) } tier = GetMaxPowerTier(move); - if (gMovesInfo[move].type == TYPE_FIGHTING - || gMovesInfo[move].type == TYPE_POISON + u32 moveType = GetMoveType(move); + if (moveType == TYPE_FIGHTING + || moveType == TYPE_POISON || move == MOVE_MULTI_ATTACK) { switch (tier) @@ -369,9 +370,10 @@ u8 GetMaxMovePower(u32 move) static u8 GetMaxPowerTier(u32 move) { - if (gMovesInfo[move].strikeCount >= 2 && gMovesInfo[move].strikeCount <= 5) + u32 strikeCount = GetMoveStrikeCount(move); + if (strikeCount >= 2 && strikeCount <= 5) { - switch(gMovesInfo[move].power) + switch(GetMovePower(move)) { case 0 ... 25: return MAX_POWER_TIER_2; case 26 ... 30: return MAX_POWER_TIER_3; @@ -382,7 +384,7 @@ static u8 GetMaxPowerTier(u32 move) } } - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_BIDE: case EFFECT_SUPER_FANG: @@ -418,7 +420,7 @@ static u8 GetMaxPowerTier(u32 move) case EFFECT_LOW_KICK: return MAX_POWER_TIER_7; case EFFECT_MULTI_HIT: - switch(gMovesInfo[move].power) + switch(GetMovePower(move)) { case 0 ... 15: return MAX_POWER_TIER_1; case 16 ... 18: return MAX_POWER_TIER_2; @@ -428,7 +430,7 @@ static u8 GetMaxPowerTier(u32 move) } } - switch (gMovesInfo[move].power) + switch (GetMovePower(move)) { case 0 ... 40: return MAX_POWER_TIER_1; case 45 ... 50: return MAX_POWER_TIER_2; @@ -470,7 +472,7 @@ void ChooseDamageNonTypesString(u8 type) // Returns the status effect that should be applied by a G-Max Move. static u32 GetMaxMoveStatusEffect(u32 move) { - u8 maxEffect = gMovesInfo[move].argument; + u8 maxEffect = GetMoveMaxEffect(move); switch (maxEffect) { // Status 1 @@ -522,7 +524,7 @@ void BS_SetMaxMoveEffect(void) { NATIVE_ARGS(); u16 effect = 0; - u8 maxEffect = gMovesInfo[gCurrentMove].argument; + u8 maxEffect = GetMoveMaxEffect(gCurrentMove); // Don't continue if the move didn't land. if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT) @@ -541,7 +543,7 @@ void BS_SetMaxMoveEffect(void) if (!NoAliveMonsForEitherParty()) { // Max Effects are ordered by stat ID. - SET_STATCHANGER(gMovesInfo[gCurrentMove].argument, 1, FALSE); + SET_STATCHANGER(maxEffect, 1, FALSE); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectRaiseStatAllies; effect++; @@ -569,7 +571,7 @@ void BS_SetMaxMoveEffect(void) break; default: // Max Effects are ordered by stat ID. - statId = gMovesInfo[gCurrentMove].argument - MAX_EFFECT_LOWER_ATTACK + 1; + statId = maxEffect - MAX_EFFECT_LOWER_ATTACK + 1; break; } SET_STATCHANGER(statId, stage, TRUE); @@ -618,7 +620,7 @@ void BS_SetMaxMoveEffect(void) case MAX_EFFECT_PSYCHIC_TERRAIN: { u32 statusFlag = 0; - switch (gMovesInfo[gCurrentMove].argument) + switch (GetMoveEffectArg_MoveProperty(gCurrentMove)) { case MAX_EFFECT_MISTY_TERRAIN: statusFlag = STATUS_FIELD_MISTY_TERRAIN; @@ -659,11 +661,12 @@ void BS_SetMaxMoveEffect(void) u8 side = GetBattlerSide(gBattlerTarget); if (!(gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES)) { + u32 moveType = GetMoveType(gCurrentMove); gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES; gSideTimers[side].damageNonTypesTimer = 5; // damage is dealt for 4 turns, ends on 5th - gSideTimers[side].damageNonTypesType = gMovesInfo[gCurrentMove].type; + gSideTimers[side].damageNonTypesType = moveType; BattleScriptPush(gBattlescriptCurrInstr + 1); - ChooseDamageNonTypesString(gMovesInfo[gCurrentMove].type); + ChooseDamageNonTypesString(moveType); gBattlescriptCurrInstr = BattleScript_DamageNonTypesStarts; effect++; } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 611c1bec59..1aeeb8afd6 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -329,7 +329,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move) case MOVE_TARGET_RANDOM: case MOVE_TARGET_BOTH: case MOVE_TARGET_FOES_AND_ALLY: - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) return PALACE_MOVE_GROUP_SUPPORT; else return PALACE_MOVE_GROUP_ATTACK; @@ -435,6 +435,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite) } } +void SpriteCB_TrainerSpawn(struct Sprite *sprite) +{ + if (!(gIntroSlideFlags & 1)) + { + sprite->x2 = 0; + if (sprite->y2 != 0) + sprite->callback = SpriteCB_TrainerSlideVertical; + else + sprite->callback = SpriteCallbackDummy; + } +} + // Slide up to 0 if necessary (used by multi battle intro) static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite) { @@ -1043,7 +1055,8 @@ void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId) void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move) { - if (gMovesInfo[move].effect == EFFECT_SUBSTITUTE || gMovesInfo[move].effect == EFFECT_SHED_TAIL) + u32 effect = GetMoveEffect(move); + if (effect == EFFECT_SUBSTITUTE || effect == EFFECT_SHED_TAIL) gBattleSpritesDataPtr->battlerData[battler].behindSubstitute = 1; } @@ -1185,7 +1198,7 @@ void CreateEnemyShadowSprite(u32 battler) { gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteIdPrimary = CreateSprite(&gSpriteTemplate_EnemyShadow, GetBattlerSpriteCoord(battler, BATTLER_COORD_X), - GetBattlerSpriteCoord(battler, BATTLER_COORD_Y), + GetBattlerSpriteCoord(battler, BATTLER_COORD_Y) + 29, 0xC8); if (gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteIdPrimary < MAX_SPRITES) { @@ -1247,9 +1260,11 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite) return; } - s8 xOffset = 0, yOffset = 0, size = SHADOW_SIZE_S; + s8 xOffset = 0, UNUSED yOffset = 0, size = SHADOW_SIZE_S; if (gAnimScriptActive || battlerSprite->invisible) + { invisible = TRUE; + } else if (transformSpecies != SPECIES_NONE) { xOffset = gSpeciesInfo[transformSpecies].enemyShadowXOffset; @@ -1267,21 +1282,19 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite) yOffset = gSpeciesInfo[species].enemyShadowYOffset + 16; size = gSpeciesInfo[species].enemyShadowSize; } - else - { - yOffset = 29; - } if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) invisible = TRUE; shadowSprite->x = battlerSprite->x + xOffset; shadowSprite->x2 = battlerSprite->x2; - shadowSprite->y = battlerSprite->y + yOffset; shadowSprite->invisible = invisible; if (B_ENEMY_MON_SHADOW_STYLE >= GEN_4 && P_GBA_STYLE_SPECIES_GFX == FALSE) + { shadowSprite->oam.tileNum = shadowSprite->tBaseTileNum + (8 * size); + shadowSprite->y = battlerSprite->y + yOffset; + } } #undef tBattlerId diff --git a/src/battle_intro.c b/src/battle_intro.c index a6b1607285..b951c163c8 100644 --- a/src/battle_intro.c +++ b/src/battle_intro.c @@ -8,6 +8,7 @@ #include "main.h" #include "scanline_effect.h" #include "task.h" +#include "test_runner.h" #include "trig.h" #include "constants/battle_partner.h" #include "constants/trainers.h" @@ -17,6 +18,7 @@ static void BattleIntroSlide2(u8); static void BattleIntroSlide3(u8); static void BattleIntroSlideLink(u8); static void BattleIntroSlidePartner(u8); +static void BattleIntroNoSlide(u8); static const u8 sBattleAnimBgCnts[] = {REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT}; @@ -149,9 +151,59 @@ static void BattleIntroSlideEnd(u8 taskId) SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); } +static void BattleIntroNoSlide(u8 taskId) +{ + switch (gTasks[taskId].tState) + { + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTasks[taskId].data[2] = 16; + gTasks[taskId].tState++; + gIntroSlideFlags &= ~1; + } + else + { + gTasks[taskId].data[2] = 1; + gTasks[taskId].tState++; + gIntroSlideFlags &= ~1; + } + break; + case 1: + gTasks[taskId].data[2]--; + if (gTasks[taskId].data[2] == 0) + { + gTasks[taskId].tState++; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + gScanlineEffect.state = 3; + } + break; + case 2: + gBattle_WIN0V -= 0xFF * 2; + if ((gBattle_WIN0V & 0xFF00) == 0) + { + gTasks[taskId].tState++; + } + break; + case 3: + gTasks[taskId].tState++; + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + break; + case 4: + BattleIntroSlideEnd(taskId); + break; + } +} + static void BattleIntroSlide1(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); gBattle_BG1_X += 6; switch (gTasks[taskId].tState) @@ -237,6 +289,8 @@ static void BattleIntroSlide1(u8 taskId) static void BattleIntroSlide2(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); switch (gTasks[taskId].tTerrain) { @@ -349,6 +403,8 @@ static void BattleIntroSlide2(u8 taskId) static void BattleIntroSlide3(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); gBattle_BG1_X += 8; switch (gTasks[taskId].tState) diff --git a/src/battle_main.c b/src/battle_main.c index a324ec9173..191d5c8b07 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -20,10 +20,12 @@ #include "data.h" #include "debug.h" #include "decompress.h" +#include "dexnav.h" #include "dma3.h" #include "event_data.h" #include "evolution_scene.h" #include "field_weather.h" +#include "generational_changes.h" #include "graphics.h" #include "gpu_regs.h" #include "international_string_util.h" @@ -162,7 +164,6 @@ EWRAM_DATA u8 gChosenMovePos = 0; EWRAM_DATA u16 gCurrentMove = 0; EWRAM_DATA u16 gChosenMove = 0; EWRAM_DATA u16 gCalledMove = 0; -EWRAM_DATA s32 gHpDealt = 0; EWRAM_DATA s32 gBideDmg[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gLastUsedItem = 0; EWRAM_DATA u16 gLastUsedAbility = 0; @@ -483,21 +484,24 @@ static void CB2_InitBattleInternal(void) else { gBattle_WIN0V = WIN_RANGE(DISPLAY_HEIGHT / 2, DISPLAY_HEIGHT / 2 + 1); - ScanlineEffect_Clear(); - - for (i = 0; i < DISPLAY_HEIGHT / 2; i++) + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) { - gScanlineEffectRegBuffers[0][i] = 0xF0; - gScanlineEffectRegBuffers[1][i] = 0xF0; - } + ScanlineEffect_Clear(); - for (; i < DISPLAY_HEIGHT; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xFF10; - gScanlineEffectRegBuffers[1][i] = 0xFF10; - } + for (i = 0; i < DISPLAY_HEIGHT / 2; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xF0; + gScanlineEffectRegBuffers[1][i] = 0xF0; + } - ScanlineEffect_SetParams(sIntroScanlineParams16Bit); + for (; i < DISPLAY_HEIGHT; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xFF10; + gScanlineEffectRegBuffers[1][i] = 0xFF10; + } + + ScanlineEffect_SetParams(sIntroScanlineParams16Bit); + } } ResetPaletteFade(); @@ -528,7 +532,8 @@ static void CB2_InitBattleInternal(void) LoadBattleTextboxAndBackground(); ResetSpriteData(); ResetTasks(); - DrawBattleEntryBackground(); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + DrawBattleEntryBackground(); FreeAllSpritePalettes(); gReservedSpritePaletteCount = MAX_BATTLERS_COUNT; SetVBlankCallback(VBlankCB_Battle); @@ -1906,8 +1911,9 @@ void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon for (j = 0; j < MAX_MON_MOVES; ++j) { + u32 pp = GetMovePP(partyEntry->moves[j]); SetMonData(mon, MON_DATA_MOVE1 + j, &partyEntry->moves[j]); - SetMonData(mon, MON_DATA_PP1 + j, &gMovesInfo[partyEntry->moves[j]].pp); + SetMonData(mon, MON_DATA_PP1 + j, &pp); } } @@ -2646,17 +2652,24 @@ void SpriteCB_WildMon(struct Sprite *sprite) { sprite->callback = SpriteCB_MoveWildMonToRight; StartSpriteAnimIfDifferent(sprite, 0); - if (WILD_DOUBLE_BATTLE) - BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8)); - else - BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8)); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + { + if (WILD_DOUBLE_BATTLE) + BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8)); + else + BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8)); + } } static void SpriteCB_MoveWildMonToRight(struct Sprite *sprite) { if ((gIntroSlideFlags & 1) == 0) { - sprite->x2 += 2; + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + sprite->x2 += 2; + else + sprite->x2 = 0; + if (sprite->x2 == 0) { sprite->callback = SpriteCB_WildMonShowHealthbox; @@ -2672,10 +2685,13 @@ static void SpriteCB_WildMonShowHealthbox(struct Sprite *sprite) SetHealthboxSpriteVisible(gHealthboxSpriteIds[sprite->sBattler]); sprite->callback = SpriteCB_WildMonAnimate; StartSpriteAnimIfDifferent(sprite, 0); - if (WILD_DOUBLE_BATTLE) - BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8)); - else - BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8)); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + { + if (WILD_DOUBLE_BATTLE) + BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8)); + else + BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8)); + } } } @@ -3134,10 +3150,11 @@ static void BattleStartClearSetData(void) void SwitchInClearSetData(u32 battler) { s32 i; + u32 effect = GetMoveEffect(gCurrentMove); struct DisableStruct disableStructCopy = gDisableStructs[battler]; ClearIllusionMon(battler); - if (gMovesInfo[gCurrentMove].effect != EFFECT_BATON_PASS) + if (effect != EFFECT_BATON_PASS) { for (i = 0; i < NUM_BATTLE_STATS; i++) gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE; @@ -3152,7 +3169,7 @@ void SwitchInClearSetData(u32 battler) } } } - if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS) + if (effect == EFFECT_BATON_PASS) { gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY_ANY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED @@ -3194,7 +3211,7 @@ void SwitchInClearSetData(u32 battler) memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct)); - if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS) + if (effect == EFFECT_BATON_PASS) { gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP; gDisableStructs[battler].battlerWithSureHit = disableStructCopy.battlerWithSureHit; @@ -3202,7 +3219,7 @@ void SwitchInClearSetData(u32 battler) gDisableStructs[battler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape; gDisableStructs[battler].embargoTimer = disableStructCopy.embargoTimer; } - else if (gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL) + else if (effect == EFFECT_SHED_TAIL) { gBattleMons[battler].status2 |= STATUS2_SUBSTITUTE; gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP; @@ -3230,6 +3247,13 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->boosterEnergyActivates &= ~(1u << battler); gBattleStruct->canPickupItem &= ~(1u << battler); + if (gBattleStruct->pursuitTarget & (1u << battler)) + { + gBattleStruct->pursuitTarget = 0; + gBattleStruct->pursuitSwitchByMove = FALSE; + gBattleStruct->pursuitStoredSwitch = 0; + } + for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { // Switched into sticky web user slot, so reset stored battler ID @@ -3360,9 +3384,13 @@ const u8* FaintClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][1] = 0; gBattleStruct->lastTakenMoveFrom[battler][2] = 0; gBattleStruct->lastTakenMoveFrom[battler][3] = 0; - gBattleStruct->pursuitTarget = 0; - gBattleStruct->pursuitSwitchByMove = FALSE; - gBattleStruct->pursuitStoredSwitch = 0; + + if (gBattleStruct->pursuitTarget & (1u << battler)) + { + gBattleStruct->pursuitTarget = 0; + gBattleStruct->pursuitSwitchByMove = FALSE; + gBattleStruct->pursuitStoredSwitch = 0; + } gBattleStruct->palaceFlags &= ~(1u << battler); gBattleStruct->boosterEnergyActivates &= ~(1u << battler); @@ -3569,7 +3597,7 @@ static void DoBattleIntro(void) } else // Skip party summary since it is a wild battle. { - if (B_FAST_INTRO == TRUE) + if (B_FAST_INTRO_PKMN_TEXT == TRUE) gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; // Don't wait for sprite, print message at the same time. else gBattleStruct->introState++; // Wait for sprite to load. @@ -3641,7 +3669,7 @@ static void DoBattleIntro(void) } else { - if (B_FAST_INTRO == TRUE) + if (B_FAST_INTRO_PKMN_TEXT == TRUE) gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; else gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM; @@ -3680,7 +3708,7 @@ static void DoBattleIntro(void) BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A); MarkBattlerForControllerExec(battler); } - if (B_FAST_INTRO == TRUE + if (B_FAST_INTRO_PKMN_TEXT == TRUE && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK))) gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; // Print at the same time as trainer sends out second mon. else @@ -3703,7 +3731,7 @@ static void DoBattleIntro(void) battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); // A hack that makes fast intro work in trainer battles too. - if (B_FAST_INTRO == TRUE + if (B_FAST_INTRO_PKMN_TEXT == TRUE && gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK)) && gSprites[gHealthboxSpriteIds[battler ^ BIT_SIDE]].callback == SpriteCallbackDummy) @@ -4838,35 +4866,35 @@ s8 GetChosenMovePriority(u32 battler) else move = gBattleMons[battler].moves[*(gBattleStruct->chosenMovePositions + battler)]; - return GetMovePriority(battler, move); + return GetBattleMovePriority(battler, move); } -s8 GetMovePriority(u32 battler, u16 move) +s8 GetBattleMovePriority(u32 battler, u16 move) { s8 priority; u16 ability = GetBattlerAbility(battler); - if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move)) + if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move)) move = GetUsableZMove(battler, move); - priority = gMovesInfo[move].priority; + priority = GetMovePriority(move); // Max Guard check - if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS) - return gMovesInfo[MOVE_MAX_GUARD].priority; + if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS) + return GetMovePriority(MOVE_MAX_GUARD); if (ability == ABILITY_GALE_WINGS - && (B_GALE_WINGS < GEN_7 || IsBattlerAtMaxHp(battler)) - && gMovesInfo[move].type == TYPE_FLYING) + && (GetGenConfig(GEN_CONFIG_GALE_WINGS) < GEN_7 || IsBattlerAtMaxHp(battler)) + && GetMoveType(move) == TYPE_FLYING) { priority++; } - else if (ability == ABILITY_PRANKSTER && IS_MOVE_STATUS(move)) + else if (ability == ABILITY_PRANKSTER && IsBattleMoveStatus(move)) { gProtectStructs[battler].pranksterElevated = 1; priority++; } - else if (gMovesInfo[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battler) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_DYNAMAX && !IsGimmickSelected(battler, GIMMICK_DYNAMAX)) + else if (GetMoveEffect(move) == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battler) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_DYNAMAX && !IsGimmickSelected(battler, GIMMICK_DYNAMAX)) { priority++; } @@ -4892,8 +4920,8 @@ s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov // Lagging Tail - always last bool32 battler1HasQuickEffect = gProtectStructs[battler1].quickDraw || gProtectStructs[battler1].usedCustapBerry; bool32 battler2HasQuickEffect = gProtectStructs[battler2].quickDraw || gProtectStructs[battler2].usedCustapBerry; - bool32 battler1HasStallingAbility = ability1 == ABILITY_STALL || (ability1 == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gChosenMoveByBattler[battler1])); - bool32 battler2HasStallingAbility = ability2 == ABILITY_STALL || (ability2 == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gChosenMoveByBattler[battler2])); + bool32 battler1HasStallingAbility = ability1 == ABILITY_STALL || (ability1 == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gChosenMoveByBattler[battler1])); + bool32 battler2HasStallingAbility = ability2 == ABILITY_STALL || (ability2 == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gChosenMoveByBattler[battler2])); if (battler1HasQuickEffect && !battler2HasQuickEffect) strikesFirst = 1; @@ -5246,7 +5274,7 @@ static bool32 TryDoMoveEffectsBeforeMoves(void) { gBattleStruct->focusPunchBattlers |= 1u << battlers[i]; gBattlerAttacker = battlers[i]; - switch (gMovesInfo[gChosenMoveByBattler[gBattlerAttacker]].effect) + switch (GetMoveEffect(gChosenMoveByBattler[gBattlerAttacker])) { case EFFECT_FOCUS_PUNCH: BattleScriptExecute(BattleScript_FocusPunchSetUp); @@ -5295,7 +5323,7 @@ static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2) // Battler 1 // Quick Draw - if (ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && gBattleStruct->quickDrawRandom[battler1]) + if (ability1 == ABILITY_QUICK_DRAW && !IsBattleMoveStatus(gChosenMoveByBattler[battler1]) && gBattleStruct->quickDrawRandom[battler1]) gProtectStructs[battler1].quickDraw = TRUE; // Quick Claw and Custap Berry if (!gProtectStructs[battler1].quickDraw @@ -5305,7 +5333,7 @@ static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2) // Battler 2 // Quick Draw - if (ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && gBattleStruct->quickDrawRandom[battler2]) + if (ability2 == ABILITY_QUICK_DRAW && !IsBattleMoveStatus(gChosenMoveByBattler[battler2]) && gBattleStruct->quickDrawRandom[battler2]) gProtectStructs[battler2].quickDraw = TRUE; // Quick Claw and Custap Berry if (!gProtectStructs[battler2].quickDraw @@ -5661,6 +5689,12 @@ static void FreeResetData_ReturnToOvOrDoEvolutions(void) { gIsFishingEncounter = FALSE; gIsSurfingEncounter = FALSE; + if (gDexNavBattle && (gBattleOutcome == B_OUTCOME_WON || gBattleOutcome == B_OUTCOME_CAUGHT)) + IncrementDexNavChain(); + else + gSaveBlock3Ptr->dexNavChain = 0; + + gDexNavBattle = FALSE; ResetSpriteData(); if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK @@ -5798,7 +5832,7 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) { u32 ateType; - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_TERA_BLAST: if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA) @@ -5850,8 +5884,8 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) // NULL can be passed to ateBoost to avoid applying ate-ability boosts when opening the summary screen in-battle. u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) { - u32 moveType = gMovesInfo[move].type; - u32 moveEffect = gMovesInfo[move].effect; + u32 moveType = GetMoveType(move); + u32 moveEffect = GetMoveEffect(move); u32 species, heldItem, holdEffect, ability, type1, type2, type3; if (move == MOVE_STRUGGLE) @@ -5946,7 +5980,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) } break; case EFFECT_CHANGE_TYPE_ON_ITEM: - if (holdEffect == gMovesInfo[move].argument) + if (holdEffect == GetMoveEffectArg_HoldEffect(move)) return ItemId_GetSecondaryId(heldItem); break; case EFFECT_REVELATION_DANCE: @@ -6054,7 +6088,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) *ateBoost = TRUE; return TYPE_NORMAL; } - else if (gMovesInfo[move].soundMove && ability == ABILITY_LIQUID_VOICE) + else if (IsSoundMove(move) && ability == ABILITY_LIQUID_VOICE) { return TYPE_WATER; } @@ -6083,13 +6117,13 @@ void SetTypeBeforeUsingMove(u32 move, u32 battler) if (moveType != TYPE_NONE) gBattleStruct->dynamicMoveType = moveType | F_DYNAMIC_TYPE_SET; - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL) || gStatuses4[battler] & STATUS4_ELECTRIFIED) gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET; // Check if a gem should activate. - if (holdEffect == HOLD_EFFECT_GEMS && GetMoveType(move) == ItemId_GetSecondaryId(heldItem)) + if (holdEffect == HOLD_EFFECT_GEMS && GetBattleMoveType(move) == ItemId_GetSecondaryId(heldItem)) { gSpecialStatuses[battler].gemParam = GetBattlerHoldEffectParam(battler); gSpecialStatuses[battler].gemBoost = TRUE; diff --git a/src/battle_message.c b/src/battle_message.c index 662473eb5d..998c8f8185 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -915,15 +915,17 @@ const u16 gMentalHerbCureStringIds[] = const u16 gStartingStatusStringIds[B_MSG_STARTING_STATUS_COUNT] = { - [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, - [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, - [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC, - [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY, - [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED, - [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED, - [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED, - [B_MSG_SET_TAILWIND_PLAYER] = STRINGID_TAILWINDBLEW, - [B_MSG_SET_TAILWIND_OPPONENT] = STRINGID_TAILWINDBLEW, + [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, + [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, + [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC, + [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY, + [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED, + [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED, + [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED, + [B_MSG_SET_TAILWIND] = STRINGID_TAILWINDBLEW, + [B_MSG_SET_RAINBOW] = STRINGID_ARAINBOWAPPEAREDONSIDE, + [B_MSG_SET_SEA_OF_FIRE] = STRINGID_SEAOFFIREENVELOPEDSIDE, + [B_MSG_SET_SWAMP] = STRINGID_SWAMPENVELOPEDSIDE, }; const u16 gTerrainStringIds[B_MSG_TERRAIN_COUNT] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 25d1f78996..0e49700e2f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -47,6 +47,7 @@ #include "pokenav.h" #include "menu_specialized.h" #include "data.h" +#include "move.h" #include "constants/abilities.h" #include "constants/battle_anim.h" #include "constants/battle_move_effects.h" @@ -1103,7 +1104,7 @@ static const u8 sTerrainToType[BATTLE_TERRAIN_COUNT] = static bool32 NoTargetPresent(u8 battler, u32 move) { if (!IsBattlerAlive(gBattlerTarget)) - gBattlerTarget = GetMoveTarget(move, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(move, NO_TARGET_OVERRIDE); switch (GetBattlerMoveTargetType(battler, move)) { @@ -1126,19 +1127,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move) return FALSE; } -static bool32 TryFormChangeBeforeMove(void) -{ - bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE); - if (!result) - result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY); - if (!result) - return FALSE; - - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_AttackerFormChange; - return TRUE; -} - bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType) { if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO) @@ -1159,7 +1147,7 @@ bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef) if (!gSpecialStatuses[battlerDef].distortedTypeMatchups && gBattleMons[battlerDef].species == SPECIES_TERAPAGOS_TERASTAL && gBattleMons[battlerDef].hp == gBattleMons[battlerDef].maxHP - && !IS_MOVE_STATUS(move) + && !IsBattleMoveStatus(move) && MoveResultHasEffect(battlerDef) && GetBattlerAbility(battlerDef) == ABILITY_TERA_SHELL) return TRUE; @@ -1169,7 +1157,7 @@ bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef) bool32 IsMoveNotAllowedInSkyBattles(u32 move) { - return ((gBattleStruct->isSkyBattle) && (gMovesInfo[gCurrentMove].skyBattleBanned)); + return (gBattleStruct->isSkyBattle && IsMoveSkyBattleBanned(gCurrentMove)); } static void Cmd_attackcanceler(void) @@ -1177,8 +1165,6 @@ static void Cmd_attackcanceler(void) CMD_ARGS(); s32 i; - u16 attackerAbility = GetBattlerAbility(gBattlerAttacker); - u32 moveType = GetMoveType(gCurrentMove); if (gBattleStruct->usedEjectItem & (1u << gBattlerAttacker)) { @@ -1187,48 +1173,22 @@ static void Cmd_attackcanceler(void) return; } - // Weight-based moves are blocked by Dynamax. - if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove)) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax; - return; - } - if (gBattleOutcome != 0) { gCurrentActionFuncId = B_ACTION_FINISHED; return; } - if (!IsBattlerAlive(gBattlerAttacker) && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + u32 effect = GetMoveEffect(gCurrentMove); + + if (!IsBattlerAlive(gBattlerAttacker) && effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) { gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; gBattlescriptCurrInstr = BattleScript_MoveEnd; return; } - if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove()) + if (AtkCanceller_MoveSuccessOrder()) return; - if (AtkCanceller_UnableToUseMove(moveType)) - return; - - if (WEATHER_HAS_EFFECT && gMovesInfo[gCurrentMove].power) - { - if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; - return; - } - else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; - return; - } - } if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF && GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND @@ -1242,22 +1202,6 @@ static void Cmd_attackcanceler(void) return; } - // Check Protean activation. - if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType)) - { - if (B_PROTEAN_LIBERO == GEN_9) - gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE; - PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); - gBattlerAbility = gBattlerAttacker; - BattleScriptPushCursor(); - PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); - gBattleCommunication[MSG_DISPLAY] = 1; - gBattlescriptCurrInstr = BattleScript_ProteanActivates; - return; - } - - if (AtkCanceller_UnableToUseMove2()) - return; if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0)) return; if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE @@ -1268,28 +1212,27 @@ static void Cmd_attackcanceler(void) gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; return; } - if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove()) - return; gHitMarker &= ~HITMARKER_ALLOW_NO_PP; // Check if no available target present on the field or if Sky Battles ban the move if ((NoTargetPresent(gBattlerAttacker, gCurrentMove) - && (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))) + && (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))) || (IsMoveNotAllowedInSkyBattles(gCurrentMove))) { - if (gMovesInfo[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling. + if (effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling. gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem; else gBattlescriptCurrInstr = BattleScript_FailedFromAtkString; - if (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) + if (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) CancelMultiTurnMoves(gBattlerAttacker); return; } + u32 isBounceable = MoveCanBeBouncedBack(gCurrentMove); if (gProtectStructs[gBattlerTarget].bounceMove - && gMovesInfo[gCurrentMove].magicCoatAffected + && isBounceable && !gBattleStruct->bouncedMoveIsUsed) { gBattleStruct->bouncedMoveIsUsed = TRUE; @@ -1310,7 +1253,7 @@ static void Cmd_attackcanceler(void) } return; } - else if (gMovesInfo[gCurrentMove].magicCoatAffected && !gBattleStruct->bouncedMoveIsUsed) + else if (isBounceable && !gBattleStruct->bouncedMoveIsUsed) { u32 battler = gBattlerTarget; @@ -1320,7 +1263,7 @@ static void Cmd_attackcanceler(void) gBattleStruct->bouncedMoveIsUsed = TRUE; } else if (IsDoubleBattle() - && gMovesInfo[gCurrentMove].target == MOVE_TARGET_OPPONENTS_FIELD + && GetBattlerMoveTargetType(battler, gCurrentMove) == MOVE_TARGET_OPPONENTS_FIELD && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) == ABILITY_MAGIC_BOUNCE) { gBattlerTarget = battler = BATTLE_PARTNER(gBattlerTarget); @@ -1348,7 +1291,7 @@ static void Cmd_attackcanceler(void) for (i = 0; i < gBattlersCount; i++) { - if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && gMovesInfo[gCurrentMove].snatchAffected) + if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && MoveCanBeSnatched(gCurrentMove)) { gProtectStructs[gBattlerByTurnOrder[i]].stealMove = FALSE; gBattleStruct->snatchedMoveIsUsed = TRUE; @@ -1377,9 +1320,9 @@ static void Cmd_attackcanceler(void) } else if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove) && (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST)) - && (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) - && gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH - && gMovesInfo[gCurrentMove].effect != EFFECT_UPPER_HAND) + && (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) + && effect != EFFECT_SUCKER_PUNCH + && effect != EFFECT_UPPER_HAND) { if (IsMoveMakingContact(gCurrentMove, gBattlerAttacker)) gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE; @@ -1459,9 +1402,10 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) { u32 effect = FALSE; u32 ability = ABILITY_NONE; + u32 moveEffect = GetMoveEffect(move); if ((gStatuses3[battler] & STATUS3_ALWAYS_HITS && gDisableStructs[battler].battlerWithSureHit == gBattlerAttacker) - || (B_TOXIC_NEVER_MISS >= GEN_6 && gMovesInfo[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON)) + || (B_TOXIC_NEVER_MISS >= GEN_6 && moveEffect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON)) || gStatuses4[battler] & STATUS4_GLAIVE_RUSH) { effect = TRUE; @@ -1469,14 +1413,14 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && !(gStatuses3[battler] & STATUS3_COMMANDER) - && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF)) + && (moveEffect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF)) { effect = TRUE; ability = ABILITY_NO_GUARD; } // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. else if (GetBattlerAbility(battler) == ABILITY_NO_GUARD - && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF)) + && (moveEffect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF)) { effect = TRUE; ability = ABILITY_NO_GUARD; @@ -1484,7 +1428,7 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) // If the target is under the effects of Telekinesis, and the move isn't a OH-KO move, move hits. else if (gStatuses3[battler] & STATUS3_TELEKINESIS && !(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE) - && gMovesInfo[move].effect != EFFECT_OHKO) + && moveEffect != EFFECT_OHKO) { effect = TRUE; } @@ -1498,9 +1442,9 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) } else if ((gStatuses3[battler] & STATUS3_COMMANDER) || (gStatuses3[battler] & STATUS3_PHANTOM_FORCE) - || ((gStatuses3[battler] & STATUS3_ON_AIR) && !(gMovesInfo[move].damagesAirborne || gMovesInfo[move].damagesAirborneDoubleDamage)) - || ((gStatuses3[battler] & STATUS3_UNDERGROUND) && !gMovesInfo[move].damagesUnderground) - || ((gStatuses3[battler] & STATUS3_UNDERWATER) && !gMovesInfo[move].damagesUnderwater)) + || ((gStatuses3[battler] & STATUS3_ON_AIR) && !(MoveDamagesAirborne(move) || MoveDamagesAirborneDoubleDamage(move))) + || ((gStatuses3[battler] & STATUS3_UNDERGROUND) && !MoveDamagesUnderground(move)) + || ((gStatuses3[battler] & STATUS3_UNDERWATER) && !MoveDamagesUnderWater(move))) { gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_MISSED; effect = TRUE; @@ -1508,10 +1452,10 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) if (WEATHER_HAS_EFFECT) { - if ((gMovesInfo[move].effect == EFFECT_THUNDER || gMovesInfo[move].effect == EFFECT_RAIN_ALWAYS_HIT) + if ((moveEffect == EFFECT_THUNDER || moveEffect == EFFECT_RAIN_ALWAYS_HIT) && IsBattlerWeatherAffected(battler, B_WEATHER_RAIN)) effect = TRUE; - else if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && gMovesInfo[move].effect == EFFECT_BLIZZARD) + else if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && moveEffect == EFFECT_BLIZZARD) effect = TRUE; if (effect) @@ -1520,11 +1464,11 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler) if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battler] & STATUS3_MINIMIZED) - && gMovesInfo[move].minimizeDoubleDamage) + && MoveIncreasesPowerToMinimizedTargets(move)) { effect = TRUE; } - else if (gMovesInfo[move].accuracy == 0) + else if (GetMoveAccuracy(move) == 0) { effect = TRUE; } @@ -1550,7 +1494,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u if (atkAbility == ABILITY_UNAWARE || atkAbility == ABILITY_KEEN_EYE || atkAbility == ABILITY_MINDS_EYE || (B_ILLUMINATE_EFFECT >= GEN_9 && atkAbility == ABILITY_ILLUMINATE)) evasionStage = DEFAULT_STAT_STAGE; - if (gMovesInfo[move].ignoresTargetDefenseEvasionStages) + if (MoveIgnoresDefenseEvasionStages(move)) evasionStage = DEFAULT_STAT_STAGE; if (defAbility == ABILITY_UNAWARE) accStage = DEFAULT_STAT_STAGE; @@ -1565,12 +1509,12 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u if (buff > MAX_STAT_STAGE) buff = MAX_STAT_STAGE; - moveAcc = gMovesInfo[move].accuracy; + moveAcc = GetMoveAccuracy(move); // Check Thunder and Hurricane on sunny weather. - if (IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && gMovesInfo[move].effect == EFFECT_THUNDER) + if (IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && GetMoveEffect(move) == EFFECT_THUNDER) moveAcc = 50; // Check Wonder Skin. - if (defAbility == ABILITY_WONDER_SKIN && IS_MOVE_STATUS(move) && moveAcc > 50) + if (defAbility == ABILITY_WONDER_SKIN && IsBattleMoveStatus(move) && moveAcc > 50) moveAcc = 50; calc = gAccuracyStageRatios[buff].dividend * moveAcc; @@ -1586,7 +1530,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u calc = (calc * 110) / 100; // 1.1 victory star boost break; case ABILITY_HUSTLE: - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) calc = (calc * 80) / 100; // 1.2 hustle loss break; } @@ -1665,6 +1609,8 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u if (move == ACC_CURR_MOVE) move = gCurrentMove; + u32 effect = GetMoveEffect(move); + abilityAtk = GetBattlerAbility(gBattlerAttacker); holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE); @@ -1687,16 +1633,16 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT || (gSpecialStatuses[gBattlerAttacker].multiHitOn && (abilityAtk == ABILITY_SKILL_LINK || holdEffectAtk == HOLD_EFFECT_LOADED_DICE - || !(gMovesInfo[move].effect == EFFECT_TRIPLE_KICK || gMovesInfo[move].effect == EFFECT_POPULATION_BOMB)))) + || !(effect == EFFECT_TRIPLE_KICK || effect == EFFECT_POPULATION_BOMB)))) { // No acc checks for second hit of Parental Bond or multi hit moves, except Triple Kick/Triple Axel/Population Bomb gBattlescriptCurrInstr = nextInstr; } else { - u32 moveType = GetMoveType(move); + u32 moveType = GetBattleMoveType(move); u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move); - bool32 calcSpreadMove = IsSpreadMove(moveTarget) && !IS_MOVE_STATUS(move); + bool32 calcSpreadMove = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(move); for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) { @@ -1727,7 +1673,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY) gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks - if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS + if (effect == EFFECT_DRAGON_DARTS && !recalcDragonDarts // So we don't jump back and forth between targets && CanTargetPartner(gBattlerAttacker, battlerDef) && !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(battlerDef))) @@ -1738,7 +1684,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u return; } - if (gMovesInfo[move].power) + if (GetMovePower(move) != 0) CalcTypeEffectivenessMultiplier(move, moveType, gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE); } } @@ -1795,7 +1741,7 @@ static void Cmd_ppreduce(void) if (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY || moveTarget == MOVE_TARGET_ALL_BATTLERS - || gMovesInfo[gCurrentMove].forcePressure) + || MoveForcesPressure(gCurrentMove)) { for (i = 0; i < gBattlersCount; i++) { @@ -1896,7 +1842,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec critChance = CRITICAL_HIT_BLOCKED; } else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS - || gMovesInfo[move].alwaysCriticalHit + || MoveAlwaysCrits(move) || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) { critChance = CRITICAL_HIT_ALWAYS; @@ -1905,7 +1851,7 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec { critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0) + 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0) - + gMovesInfo[move].criticalHitStage + + GetMoveCriticalHitStage(move) + GetHoldEffectCritChanceIncrease(battlerAtk, holdEffectAtk) + 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS) + (abilityAtk == ABILITY_SUPER_LUCK) @@ -1959,7 +1905,7 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec u32 farfetchdLeekScaler = 8; s32 critChance = 0; - s32 moveCritStage = gMovesInfo[gCurrentMove].criticalHitStage; + s32 moveCritStage = GetMoveCriticalHitStage(gCurrentMove); s32 bonusCritStage = gBattleStruct->bonusCritStages[battlerAtk]; // G-Max Chi Strike u32 abilityAtk = GetBattlerAbility(battlerAtk); u32 abilityDef = GetBattlerAbility(battlerDef); @@ -2003,7 +1949,7 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec // Guaranteed crits else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS - || gMovesInfo[move].alwaysCriticalHit == TRUE + || MoveAlwaysCrits(move) || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) { critChance = -2; @@ -2026,7 +1972,7 @@ static void Cmd_critcalc(void) u32 partySlot = gBattlerPartyIndexes[gBattlerAttacker]; u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); - bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IS_MOVE_STATUS(gCurrentMove); + bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove); gPotentialItemEffectBattler = gBattlerAttacker; for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) @@ -2080,8 +2026,8 @@ static void Cmd_critcalc(void) static inline void GetShellSideArmCategory(u32 battlerDef) { - if (gMovesInfo[gCurrentMove].effect == EFFECT_SHELL_SIDE_ARM) - gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][battlerDef] != gMovesInfo[gCurrentMove].category); + if (GetMoveEffect(gCurrentMove) == EFFECT_SHELL_SIDE_ARM) + gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][battlerDef] != GetMoveCategory(gCurrentMove)); } static void Cmd_damagecalc(void) @@ -2099,7 +2045,7 @@ static void Cmd_damagecalc(void) struct DamageCalculationData damageCalcData; damageCalcData.battlerAtk = gBattlerAttacker; damageCalcData.move = gCurrentMove; - damageCalcData.moveType = GetMoveType(gCurrentMove); + damageCalcData.moveType = GetBattleMoveType(gCurrentMove); damageCalcData.randomFactor = TRUE; damageCalcData.updateFlags = TRUE; @@ -2146,7 +2092,7 @@ static void Cmd_typecalc(void) if (!IsSpreadMove(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove))) // Handled in CANCELLER_MULTI_TARGET_MOVES for Spread Moves { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE); } @@ -2162,7 +2108,8 @@ static void Cmd_adjustdamage(void) u32 rand = Random() % 100; u32 affectionScore = GetBattlerAffectionHearts(gBattlerTarget); u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); - bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IS_MOVE_STATUS(gCurrentMove); + u32 moveEffect = GetMoveEffect(gCurrentMove); + bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove); for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) { @@ -2184,7 +2131,7 @@ static void Cmd_adjustdamage(void) gBattleStruct->enduredDamage |= 1u << battlerDef; goto END; } - if (GetBattlerAbility(battlerDef) == ABILITY_ICE_FACE && IS_MOVE_PHYSICAL(gCurrentMove) && gBattleMons[battlerDef].species == SPECIES_EISCUE) + if (GetBattlerAbility(battlerDef) == ABILITY_ICE_FACE && IsBattleMovePhysical(gCurrentMove) && gBattleMons[battlerDef].species == SPECIES_EISCUE) { // Damage deals typeless 0 HP. gBattleStruct->moveResultFlags[battlerDef] &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE); @@ -2225,7 +2172,7 @@ static void Cmd_adjustdamage(void) gSpecialStatuses[battlerDef].affectionEndured = TRUE; } - if (gMovesInfo[gCurrentMove].effect != EFFECT_FALSE_SWIPE + if (moveEffect != EFFECT_FALSE_SWIPE && !gProtectStructs[battlerDef].endured && !gSpecialStatuses[battlerDef].focusBanded && !gSpecialStatuses[battlerDef].focusSashed @@ -2271,7 +2218,7 @@ static void Cmd_adjustdamage(void) && MoveResultHasEffect(gBattlerTarget) && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gBattleMons[gBattlerAttacker].item - && gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE + && moveEffect != EFFECT_PLEDGE && gCurrentMove != MOVE_STRUGGLE) { BattleScriptPushCursor(); @@ -2366,7 +2313,7 @@ static inline bool32 TryStrongWindsWeakenAttack(u32 battlerDef, u32 moveType) { if (gBattleWeather & B_WEATHER_STRONG_WINDS && WEATHER_HAS_EFFECT) { - if (gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS + if (GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS && IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING) && gTypeEffectivenessTable[moveType][TYPE_FLYING] >= UQ_4_12(2.0) && !gBattleStruct->printedStrongWindsWeakenedAttack) @@ -2414,7 +2361,7 @@ static inline bool32 TryActivateWeakenessBerry(u32 battlerDef) static bool32 ProcessPreAttackAnimationFuncs(void) { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); if (IsDoubleSpreadMove()) { u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); @@ -2476,7 +2423,7 @@ static void Cmd_attackanimation(void) && gCurrentMove != MOVE_SUBSTITUTE && gCurrentMove != MOVE_ALLY_SWITCH // In a wild double battle gotta use the teleport animation if two wild pokemon are alive. - && !(gMovesInfo[gCurrentMove].effect == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))) + && !(GetMoveEffect(gCurrentMove) == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))) { BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_Pausex20; @@ -2636,13 +2583,12 @@ static void Cmd_datahpupdate(void) if (gSpecialStatuses[battler].shellBellDmg == 0) gSpecialStatuses[battler].shellBellDmg = gBattleStruct->moveDamage[battler]; gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler]; - gHpDealt = gBattleStruct->moveDamage[battler]; } else { if (gSpecialStatuses[battler].shellBellDmg == 0) gSpecialStatuses[battler].shellBellDmg = gDisableStructs[battler].substituteHP; - gHpDealt = gDisableStructs[battler].substituteHP; + gBattleStruct->moveDamage[battler] = gDisableStructs[battler].substituteHP; gDisableStructs[battler].substituteHP = 0; } // check substitute fading @@ -2700,25 +2646,26 @@ static void Cmd_datahpupdate(void) if (gBattleMons[battler].hp > gBattleStruct->moveDamage[battler]) { gBattleMons[battler].hp -= gBattleStruct->moveDamage[battler]; - gHpDealt = gBattleStruct->moveDamage[battler]; } else { - gHpDealt = gBattleMons[battler].hp; + gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp; gBattleMons[battler].hp = 0; } // Record damage for Shell Bell if (gSpecialStatuses[battler].shellBellDmg == 0 && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE)) - gSpecialStatuses[battler].shellBellDmg = gHpDealt; + gSpecialStatuses[battler].shellBellDmg = gBattleStruct->moveDamage[battler]; + + u32 effect = GetMoveEffect(gCurrentMove); // Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are // used in combination as general damage trackers for other purposes. specialDmg is additionally used // to help determine if a fire move should defrost the target. - if (IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && gMovesInfo[gCurrentMove].effect != EFFECT_PAIN_SPLIT) + if (IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && effect != EFFECT_PAIN_SPLIT) { - gProtectStructs[battler].physicalDmg = gHpDealt; - gSpecialStatuses[battler].physicalDmg = gHpDealt; + gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler]; + gSpecialStatuses[battler].physicalDmg = gBattleStruct->moveDamage[battler]; if (cmd->battler == BS_TARGET) { gProtectStructs[battler].physicalBattlerId = gBattlerAttacker; @@ -2730,11 +2677,11 @@ static void Cmd_datahpupdate(void) gSpecialStatuses[battler].physicalBattlerId = gBattlerTarget; } } - else if (!IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && gMovesInfo[gCurrentMove].effect != EFFECT_PAIN_SPLIT) + else if (!IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && effect != EFFECT_PAIN_SPLIT) { // Record special damage/attacker for Mirror Coat - gProtectStructs[battler].specialDmg = gHpDealt; - gSpecialStatuses[battler].specialDmg = gHpDealt; + gProtectStructs[battler].specialDmg = gBattleStruct->moveDamage[battler]; + gSpecialStatuses[battler].specialDmg = gBattleStruct->moveDamage[battler]; if (cmd->battler == BS_TARGET) { gProtectStructs[battler].specialBattlerId = gBattlerAttacker; @@ -2888,7 +2835,7 @@ static void Cmd_resultmessage(void) if (*moveResultFlags & MOVE_RESULT_MISSED && (!(*moveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleStruct->missStringId[gBattlerTarget] > B_MSG_AVOIDED_ATK)) { - if (gMultiHitCounter && gMultiHitCounter < gMovesInfo[gCurrentMove].strikeCount) + if (gMultiHitCounter && gMultiHitCounter < GetMoveStrikeCount(gCurrentMove)) { gMultiHitCounter = 0; *moveResultFlags &= ~MOVE_RESULT_MISSED; @@ -3071,6 +3018,8 @@ static void Cmd_waitmessage(void) else { u16 toWait = cmd->time; + if (gTestRunnerHeadless) + gPauseCounterBattle = toWait; if (++gPauseCounterBattle >= toWait) { gPauseCounterBattle = 0; @@ -3185,7 +3134,8 @@ void SetMoveEffect(bool32 primary, bool32 certain) bool32 statusChanged = FALSE; bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR); u32 flags = 0; - u16 battlerAbility; + u32 battlerAbility; + u32 side; bool8 activateAfterFaint = FALSE; // NULL move effect @@ -3237,15 +3187,9 @@ void SetMoveEffect(bool32 primary, bool32 certain) gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN; if (!primary && affectsUser != MOVE_EFFECT_AFFECTS_USER - && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) - && (battlerAbility == ABILITY_SHIELD_DUST || GetBattlerHoldEffect(gEffectBattler, TRUE) == HOLD_EFFECT_COVERT_CLOAK)) - { - if (battlerAbility == ABILITY_SHIELD_DUST) - RecordAbilityBattle(gEffectBattler, battlerAbility); - else - RecordItemEffectBattle(gEffectBattler, HOLD_EFFECT_COVERT_CLOAK); + && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) + && IsMoveEffectBlockedByTarget(battlerAbility)) INCREMENT_RESET_RETURN - } if (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) && !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION) @@ -3253,7 +3197,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT) && TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) - && !(gMovesInfo[gCurrentMove].effect == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker]) + && !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker]) && !primary && gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING) INCREMENT_RESET_RETURN @@ -3360,7 +3304,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) if (B_STATUS_TYPE_IMMUNITY == GEN_1) { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType)) break; } @@ -3373,7 +3317,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) case STATUS1_FREEZE: if (B_STATUS_TYPE_IMMUNITY == GEN_1) { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType)) break; } @@ -3414,7 +3358,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) } if (B_STATUS_TYPE_IMMUNITY == GEN_1) { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType)) break; } @@ -3484,7 +3428,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) case STATUS1_FROSTBITE: if (B_STATUS_TYPE_IMMUNITY == GEN_1) { - u32 moveType = GetMoveType(gCurrentMove); + u32 moveType = GetBattleMoveType(gCurrentMove); if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType)) break; } @@ -4068,9 +4012,11 @@ void SetMoveEffect(bool32 primary, bool32 certain) gBattleMons[gBattlerAttacker].status2 |= STATUS2_ESCAPE_PREVENTION; break; case MOVE_EFFECT_REMOVE_ARG_TYPE: + { + u32 type = GetMoveArgType(gCurrentMove); // This seems unnecessary but is done to make it work properly with Parental Bond BattleScriptPush(gBattlescriptCurrInstr + 1); - switch (gMovesInfo[gCurrentMove].argument) + switch (type) { case TYPE_FIRE: // Burn Up gBattlescriptCurrInstr = BattleScript_RemoveFireType; @@ -4082,8 +4028,9 @@ void SetMoveEffect(bool32 primary, bool32 certain) gBattlescriptCurrInstr = BattleScript_RemoveGenericType; break; } - RemoveBattlerType(gEffectBattler, gMovesInfo[gCurrentMove].argument); + RemoveBattlerType(gEffectBattler, type); break; + } case MOVE_EFFECT_ROUND: TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it gBattlescriptCurrInstr++; @@ -4275,6 +4222,117 @@ void SetMoveEffect(bool32 primary, bool32 certain) } } break; + case MOVE_EFFECT_ION_DELUGE: + if (!(gFieldStatuses & STATUS_FIELD_ION_DELUGE)) + { + gFieldStatuses |= STATUS_FIELD_ION_DELUGE; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectIonDeluge; + } + break; + // TODO: The moves aromatherapy and heal bell need a refactor first + // case MOVE_EFFECT_AROMATHERAPY: + // break; + case MOVE_EFFECT_HAZE: + for (i = 0; i < gBattlersCount; i++) + TryResetBattlerStatChanges(i); + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectHaze; + break; + case MOVE_EFFECT_LEECH_SEED: + if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !(gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED)) + { + gStatuses3[gBattlerTarget] |= gBattlerAttacker; + gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectLeechSeed; + } + break; + case MOVE_EFFECT_REFLECT: + side = GetBattlerSide(gBattlerAttacker); + if (!(gSideStatuses[side] & SIDE_STATUS_REFLECT)) + { + gSideStatuses[side] |= SIDE_STATUS_REFLECT; + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) + gSideTimers[side].reflectTimer = 8; + else + gSideTimers[side].reflectTimer = 5; + gSideTimers[side].reflectBattlerId = gBattlerAttacker; + + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE; + else + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectReflect; + } + break; + case MOVE_EFFECT_LIGHT_SCREEN: + side = GetBattlerSide(gBattlerAttacker); + if (!(gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN)) + { + gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN; + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) + gSideTimers[side].lightscreenTimer = 8; + else + gSideTimers[side].lightscreenTimer = 5; + gSideTimers[side].lightscreenBattlerId = gBattlerAttacker; + + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE; + else + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE; + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectLightScreen; + } + break; + case MOVE_EFFECT_SALT_CURE: + if (!(gStatuses4[gBattlerTarget] & STATUS4_SALT_CURE)) + { + gStatuses4[gBattlerTarget] |= STATUS4_SALT_CURE; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectSaltCure; + } + break; + case MOVE_EFFECT_EERIE_SPELL: + if (gLastMoves[gBattlerTarget] != MOVE_NONE && gLastMoves[gBattlerTarget] != 0xFFFF) + { + u32 i; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i]) + break; + } + + if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] != 0) + { + u32 ppToDeduct = 3; + + if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct) + ppToDeduct = gBattleMons[gBattlerTarget].pp[i]; + + PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget]) + ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1); + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) + gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct; + if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i)) + && !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED)) + { + BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]); + MarkBattlerForControllerExec(gBattlerTarget); + } + + if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF) + CancelMultiTurnMoves(gBattlerTarget); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_MoveEffectEerieSpell; + } + } + break; } } } @@ -4309,10 +4367,11 @@ static void Cmd_setadditionaleffects(void) if (MoveResultHasEffect(gBattlerTarget)) { - if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(gCurrentMove); + if (numAdditionalEffects > gBattleStruct->additionalEffectsCounter) { u32 percentChance; - const struct AdditionalEffect *additionalEffect = &gMovesInfo[gCurrentMove].additionalEffects[gBattleStruct->additionalEffectsCounter]; + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(gCurrentMove, gBattleStruct->additionalEffectsCounter); const u8 *currentPtr = gBattlescriptCurrInstr; // Various checks for if this move effect can be applied this turn @@ -4338,7 +4397,7 @@ static void Cmd_setadditionaleffects(void) // Call setadditionaleffects again in the case of a move with multiple effects gBattleStruct->additionalEffectsCounter++; - if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter) + if (numAdditionalEffects > gBattleStruct->additionalEffectsCounter) gBattleScripting.moveEffect = MOVE_EFFECT_CONTINUE; else gBattleScripting.moveEffect = gBattleStruct->additionalEffectsCounter = 0; @@ -5462,6 +5521,8 @@ static void Cmd_pause(void) if (gBattleControllerExecFlags == 0) { u16 value = cmd->frames; + if (gTestRunnerHeadless) + gPauseCounterBattle = value; if (++gPauseCounterBattle >= value) { gPauseCounterBattle = 0; @@ -5879,21 +5940,23 @@ static void Cmd_moveend(void) endState = cmd->endState; holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE); - moveType = GetMoveType(gCurrentMove); + moveType = GetBattleMoveType(gCurrentMove); + + u32 moveEffect = GetMoveEffect(gCurrentMove); do { switch (gBattleScripting.moveendState) { case MOVEEND_SUM_DAMAGE: // Sum and store damage dealt for multi strike recoil - gBattleScripting.savedDmg += gHpDealt; + gBattleScripting.savedDmg += gBattleStruct->moveDamage[gBattlerTarget]; gBattleScripting.moveendState++; break; case MOVEEND_PROTECT_LIKE_EFFECT: if (gProtectStructs[gBattlerAttacker].touchedProtectLike) { if (gProtectStructs[gBattlerTarget].spikyShielded - && gMovesInfo[gCurrentMove].effect != EFFECT_COUNTER + && moveEffect != EFFECT_COUNTER && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) { gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; @@ -5928,7 +5991,8 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_BanefulBunkerEffect; effect = 1; } - else if (gProtectStructs[gBattlerTarget].obstructed && gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH && gMovesInfo[gCurrentMove].effect != EFFECT_UPPER_HAND) + else if (gProtectStructs[gBattlerTarget].obstructed + && moveEffect != EFFECT_SUCKER_PUNCH && moveEffect != EFFECT_UPPER_HAND) { gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; i = gBattlerAttacker; @@ -5976,18 +6040,18 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_ABSORB: - if (gMovesInfo[gCurrentMove].effect == EFFECT_ABSORB + if (moveEffect == EFFECT_ABSORB && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && IsBattlerTurnDamaged(gBattlerTarget)) { - if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && gMovesInfo[gCurrentMove].healingMove) + if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealingMove(gCurrentMove)) { gBattleScripting.moveendState++; break; } else if (IsBattlerAlive(gBattlerAttacker) && MoveResultHasEffect(gBattlerTarget)) { - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * gMovesInfo[gCurrentMove].argument / 100)); + gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100)); gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]); gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE; effect = TRUE; @@ -6016,7 +6080,7 @@ static void Cmd_moveend(void) && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget) && MoveResultHasEffect(gBattlerTarget) && IsBattlerTurnDamaged(gBattlerTarget) - && !IS_MOVE_STATUS(gCurrentMove) + && !IsBattleMoveStatus(gCurrentMove) && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)) { SET_STATCHANGER(STAT_ATK, 1, FALSE); @@ -6043,7 +6107,7 @@ static void Cmd_moveend(void) if (gBattleMons[gBattlerTarget].status1 & STATUS1_FROSTBITE && IsBattlerAlive(gBattlerTarget) && gBattlerAttacker != gBattlerTarget - && gMovesInfo[originallyUsedMove].thawsUser + && MoveThawsUser(originallyUsedMove) && MoveResultHasEffect(gBattlerTarget)) { gBattleMons[gBattlerTarget].status1 &= ~STATUS1_FROSTBITE; @@ -6056,30 +6120,31 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_RECOIL: + { + u32 moveRecoil = GetMoveRecoil(gCurrentMove); if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) { gBattleScripting.moveendState++; break; } - else if (gMovesInfo[gCurrentMove].recoil > 0 + else if (moveRecoil > 0 && MoveResultHasEffect(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker) && gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one { - gBattleStruct->moveDamage[gBattlerAttacker] = max(1, gBattleScripting.savedDmg * max(1, gMovesInfo[gCurrentMove].recoil) / 100); + gBattleStruct->moveDamage[gBattlerAttacker] = max(1, gBattleScripting.savedDmg * max(1, moveRecoil) / 100); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil; effect = TRUE; } - else if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION && !IsAbilityOnField(ABILITY_DAMP)) + else if (moveEffect == EFFECT_EXPLOSION && !IsAbilityOnField(ABILITY_DAMP)) { gBattleStruct->moveDamage[gBattlerAttacker] = 0; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_FaintAttackerForExplosion; effect = TRUE; } - else if ((gMovesInfo[gCurrentMove].effect == EFFECT_MAX_HP_50_RECOIL - || gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN) + else if ((moveEffect == EFFECT_MAX_HP_50_RECOIL || moveEffect == EFFECT_MIND_BLOWN) && IsBattlerAlive(gBattlerAttacker) && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) @@ -6091,6 +6156,7 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; + } case MOVEEND_ITEM_EFFECTS_ATTACKER: if (ItemBattleEffects(ITEMEFFECT_MOVE_END, gBattlerAttacker, FALSE)) effect = TRUE; @@ -6136,8 +6202,7 @@ static void Cmd_moveend(void) && gChosenMove != MOVE_STRUGGLE && (*choicedMoveAtk == MOVE_NONE || *choicedMoveAtk == MOVE_UNAVAILABLE)) { - if ((gMovesInfo[gChosenMove].effect == EFFECT_BATON_PASS - || gMovesInfo[gChosenMove].effect == EFFECT_HEALING_WISH) + if ((moveEffect == EFFECT_BATON_PASS || moveEffect == EFFECT_HEALING_WISH) && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED)) { gBattleScripting.moveendState++; @@ -6205,18 +6270,21 @@ static void Cmd_moveend(void) } break; case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts, Wake-Up Slap, Sparkling Aria - if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument) + { + u32 argStatus = GetMoveEffectArg_Status(gCurrentMove); + if ((gBattleMons[gBattlerTarget].status1 & argStatus) && IsBattlerAlive(gBattlerTarget) - && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove) + && (gBattleStruct->numSpreadTargets > 1 || !IsMoveEffectBlockedByTarget(GetBattlerAbility(gBattlerTarget)))) { - gBattleMons[gBattlerTarget].status1 &= ~(gMovesInfo[gCurrentMove].argument); + gBattleMons[gBattlerTarget].status1 &= ~(argStatus); BtlController_EmitSetMonData(gBattlerTarget, 0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerTarget].status1); MarkBattlerForControllerExec(gBattlerTarget); effect = TRUE; BattleScriptPush(gBattlescriptCurrInstr); - switch (gMovesInfo[gCurrentMove].argument) + switch (argStatus) { case STATUS1_PARALYSIS: gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; @@ -6243,6 +6311,7 @@ static void Cmd_moveend(void) } break; // MOVE_EFFECT_REMOVE_STATUS } + } gBattleStruct->moveEffect2 = 0; gBattleScripting.moveendState++; break; // MOVEEND_MOVE_EFFECTS2 @@ -6298,7 +6367,7 @@ static void Cmd_moveend(void) break; case MOVEEND_NUM_HITS: if (gBattlerAttacker != gBattlerTarget - && gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS + && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS && MoveResultHasEffect(gBattlerTarget) && IsBattlerTurnDamaged(gBattlerTarget)) { @@ -6350,7 +6419,7 @@ static void Cmd_moveend(void) gBattleStruct->lastMoveFailed &= ~(1u << gBattlerAttacker); // Set ShellTrap to activate after the attacker's turn if target was hit by a physical move. - if (gMovesInfo[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_SHELL_TRAP + if (GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP && gBattlerTarget != gBattlerAttacker && GetBattlerSide(gBattlerTarget) != GetBattlerSide(gBattlerAttacker) && gProtectStructs[gBattlerTarget].physicalDmg @@ -6383,10 +6452,10 @@ static void Cmd_moveend(void) gBattleStruct->dynamax.lastUsedBaseMove = gBattleStruct->dynamax.baseMoves[gBattlerAttacker]; } } + u32 originalEffect = GetMoveEffect(originallyUsedMove); if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker)) && !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker)) - && gMovesInfo[originallyUsedMove].effect != EFFECT_BATON_PASS - && gMovesInfo[originallyUsedMove].effect != EFFECT_HEALING_WISH) + && originalEffect != EFFECT_BATON_PASS && originalEffect != EFFECT_HEALING_WISH) { if (gHitMarker & HITMARKER_OBEYS) { @@ -6395,7 +6464,7 @@ static void Cmd_moveend(void) gLastMoves[gBattlerAttacker] = gChosenMove; RecordKnownMove(gBattlerAttacker, gChosenMove); gLastResultingMoves[gBattlerAttacker] = gCurrentMove; - gLastUsedMoveType[gBattlerAttacker] = GetMoveType(gCurrentMove); + gLastUsedMoveType[gBattlerAttacker] = GetBattleMoveType(gCurrentMove); } } else @@ -6417,7 +6486,7 @@ static void Cmd_moveend(void) else { gLastLandedMoves[gBattlerTarget] = gCurrentMove; - gLastHitByType[gBattlerTarget] = GetMoveType(gCurrentMove); + gLastHitByType[gBattlerTarget] = GetBattleMoveType(gCurrentMove); } } else @@ -6430,7 +6499,7 @@ static void Cmd_moveend(void) case MOVEEND_MIRROR_MOVE: // mirror move if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker)) && !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker)) - && !gMovesInfo[originallyUsedMove].mirrorMoveBanned + && !IsMoveMirrorMoveBanned(originallyUsedMove) && gHitMarker & HITMARKER_OBEYS && gBattlerAttacker != gBattlerTarget && !(gHitMarker & HITMARKER_FAINTED(gBattlerTarget)) @@ -6467,10 +6536,10 @@ static void Cmd_moveend(void) MoveValuesCleanUp(); gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect; - if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION) + if (moveEffect == EFFECT_EXPLOSION) BattleScriptPush(gBattleMoveEffects[EFFECT_HIT].battleScript); // Edge case for Explosion not changing targets else - BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove)); + BattleScriptPush(GetMoveBattleScript(gCurrentMove)); gBattlescriptCurrInstr = BattleScript_FlushMessageBox; return; } @@ -6492,7 +6561,7 @@ static void Cmd_moveend(void) gBattleScripting.animTurn = 0; gBattleScripting.animTargetsHit = 0; MoveValuesCleanUp(); - BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove)); + BattleScriptPush(GetMoveBattleScript(gCurrentMove)); gBattlescriptCurrInstr = BattleScript_FlushMessageBox; return; } @@ -6510,17 +6579,17 @@ static void Cmd_moveend(void) if (MoveResultHasEffect(gBattlerTarget) && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gMultiHitCounter - && !(gMovesInfo[gCurrentMove].effect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case + && !(moveEffect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case { gMultiHitCounter--; - if (!IsBattlerAlive(gBattlerTarget) && gMovesInfo[gCurrentMove].effect != EFFECT_DRAGON_DARTS) + if (!IsBattlerAlive(gBattlerTarget) && moveEffect != EFFECT_DRAGON_DARTS) gMultiHitCounter = 0; gBattleScripting.multihitString[4]++; if (gMultiHitCounter == 0) { BattleScriptPushCursor(); - if (gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty()) + if (GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty()) gBattlescriptCurrInstr = BattleScript_ScaleShot; else gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings; @@ -6528,7 +6597,7 @@ static void Cmd_moveend(void) } else { - if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS + if (moveEffect == EFFECT_DRAGON_DARTS && !(gBattleStruct->moveResultFlags[BATTLE_PARTNER(gBattlerTarget)] & MOVE_RESULT_MISSED) // didn't miss the other target && CanTargetPartner(gBattlerAttacker, gBattlerTarget) && !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(gBattlerTarget))) @@ -6550,7 +6619,7 @@ static void Cmd_moveend(void) gSpecialStatuses[gBattlerTarget].focusSashed = 0; // Delete this line to make Focus Sash last for the duration of the whole move turn. gSpecialStatuses[gBattlerAttacker].multiHitOn = TRUE; MoveValuesCleanUp(); - BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove)); + BattleScriptPush(GetMoveBattleScript(gCurrentMove)); gBattlescriptCurrInstr = BattleScript_FlushMessageBox; return; } @@ -6643,12 +6712,12 @@ static void Cmd_moveend(void) if (IsBattlerAlive(battler) && CountUsablePartyMons(battler) > 0 // Has mon to switch into // Does not activate if attacker used Parting Shot and can switch out - && !(gMovesInfo[gCurrentMove].effect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker)) + && !(moveEffect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker)) ) { gBattleScripting.battler = battler; gLastUsedItem = gBattleMons[battler].item; - if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) + if (moveEffect == EFFECT_HIT_ESCAPE) gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection effect = TRUE; BattleScriptPushCursor(); @@ -6660,19 +6729,13 @@ static void Cmd_moveend(void) } else // Eject Pack { - if (gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT) - { - gBattlescriptCurrInstr = BattleScript_EjectPackMissesTiming; - gProtectStructs[battler].statFell = FALSE; - } - else + if (!(gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT)) { gBattlescriptCurrInstr = BattleScript_EjectPackActivates; AI_DATA->ejectPackSwitch = TRUE; - // Are these 2 lines below needed? - gProtectStructs[battler].statFell = FALSE; gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; } + gProtectStructs[battler].statFell = FALSE; } break; // Only the fastest Eject item activates } @@ -6705,7 +6768,7 @@ static void Cmd_moveend(void) redCardBattlers |= (1u << i); } if (redCardBattlers - && (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed) + && (moveEffect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed) && IsBattlerAlive(gBattlerAttacker) && !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) && GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG) @@ -6730,7 +6793,7 @@ static void Cmd_moveend(void) gBattleScripting.battler = battler; gEffectBattler = gBattlerAttacker; gBattleStruct->redCardActivates = TRUE; - if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) + if (moveEffect == EFFECT_HIT_ESCAPE) gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection BattleScriptPushCursor(); if (gBattleStruct->commanderActive[gBattlerAttacker] != SPECIES_NONE) @@ -6793,7 +6856,7 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_DANCER: // Special case because it's so annoying - if (gMovesInfo[gCurrentMove].danceMove && !gBattleStruct->snatchedMoveIsUsed) + if (IsDanceMove(gCurrentMove) && !gBattleStruct->snatchedMoveIsUsed) { u32 battler, nextDancer = 0; bool32 hasDancerTriggered = FALSE; @@ -7125,7 +7188,7 @@ static void Cmd_switchindataupdate(void) gBattleMons[battler].item = ITEM_NONE; } - if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS) + if (GetMoveEffect(gCurrentMove) == EFFECT_BATON_PASS) { for (i = 0; i < NUM_BATTLE_STATS; i++) { @@ -7711,7 +7774,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { gDisableStructs[battler].stealthRockDone = TRUE; - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(gMovesInfo[MOVE_STEALTH_ROCK].type, battler); + gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_STEALTH_ROCK), battler); if (gBattleStruct->moveDamage[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_STEALTHROCKDMG); @@ -7770,7 +7833,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) && GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD) { gDisableStructs[battler].steelSurgeDone = TRUE; - gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(gMovesInfo[MOVE_G_MAX_STEELSURGE].type, battler); + gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_G_MAX_STEELSURGE), battler); if (gBattleStruct->moveDamage[battler] != 0) SetDmgHazardsBattlescript(battler, B_MSG_SHARPSTEELDMG); @@ -8394,7 +8457,7 @@ static void Cmd_jumptocalledmove(void) else gChosenMove = gCurrentMove = gCalledMove; - gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove); + gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove); } static void Cmd_statusanimation(void) @@ -8605,7 +8668,7 @@ static void Cmd_removeitem(void) // Popped Air Balloon cannot be restored by any means. // Corroded items cannot be restored either. if (GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_AIR_BALLOON - && gMovesInfo[gCurrentMove].effect != EFFECT_CORROSIVE_GAS) + && GetMoveEffect(gCurrentMove) != EFFECT_CORROSIVE_GAS) gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = itemId; // Remember if switched out gBattleMons[battler].item = ITEM_NONE; @@ -9034,7 +9097,7 @@ static void Cmd_useitemonopponent(void) static bool32 HasAttackerFaintedTarget(void) { if (MoveResultHasEffect(gBattlerTarget) - && !IS_MOVE_STATUS(gCurrentMove) + && !IsBattleMoveStatus(gCurrentMove) && (gLastHitBy[gBattlerTarget] == 0xFF || gLastHitBy[gBattlerTarget] == gBattlerAttacker) && gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget && gBattlerTarget != gBattlerAttacker @@ -9297,11 +9360,11 @@ static bool32 IsElectricAbilityAffected(u32 battler, u32 ability) u32 moveType; if (gBattleStruct->dynamicMoveType == 0) - moveType = gMovesInfo[gCurrentMove].type; + moveType = GetMoveType(gCurrentMove); else if (!(gBattleStruct->dynamicMoveType & F_DYNAMIC_TYPE_IGNORE_PHYSICALITY)) moveType = gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK; else - moveType = gMovesInfo[gCurrentMove].type; + moveType = GetMoveType(gCurrentMove); if (moveType == TYPE_ELECTRIC && (ability != ABILITY_LIGHTNING_ROD || B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) @@ -9806,7 +9869,7 @@ static void Cmd_various(void) case VARIOUS_GET_MOVE_TARGET: { VARIOUS_ARGS(); - gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); break; } case VARIOUS_GET_BATTLER_FAINTED: @@ -10191,7 +10254,7 @@ static void Cmd_various(void) case VARIOUS_TRY_ACTIVATE_FELL_STINGER: { VARIOUS_ARGS(); - if (gMovesInfo[gCurrentMove].effect == EFFECT_FELL_STINGER + if (GetMoveEffect(gCurrentMove) == EFFECT_FELL_STINGER && HasAttackerFaintedTarget() && !NoAliveMonsForEitherParty() && CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)) @@ -10235,7 +10298,7 @@ static void Cmd_various(void) gBattlescriptCurrInstr = cmd->failInstr; else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) gBattlescriptCurrInstr = cmd->failInstr; - else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]])) + else if (IsBattleMoveStatus(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]])) gBattlescriptCurrInstr = cmd->failInstr; else gBattlescriptCurrInstr = cmd->nextInstr; @@ -10317,12 +10380,12 @@ static void Cmd_various(void) { VARIOUS_ARGS(const u8 *failInstr); u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]; - if (IS_MOVE_STATUS(move) || gMovesInfo[move].meFirstBanned + if (IsBattleMoveStatus(move) || IsMoveMeFirstBanned(move) || GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) gBattlescriptCurrInstr = cmd->failInstr; else { - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move)) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move)) { gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move; gCalledMove = GetTypeBasedZMove(move); @@ -10332,7 +10395,7 @@ static void Cmd_various(void) gCalledMove = move; } gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gStatuses3[gBattlerAttacker] |= STATUS3_ME_FIRST; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -10366,15 +10429,16 @@ static void Cmd_various(void) VARIOUS_ARGS(const u8 *failInstr); u32 types[3]; GetBattlerTypes(gBattlerTarget, FALSE, types); - if ((types[0] == gMovesInfo[gCurrentMove].type && types[1] == gMovesInfo[gCurrentMove].type) + u32 moveType = GetMoveType(gCurrentMove); + if ((types[0] == moveType && types[1] == moveType) || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA) { gBattlescriptCurrInstr = cmd->failInstr; } else { - SET_BATTLER_TYPE(gBattlerTarget, gMovesInfo[gCurrentMove].type); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].type); + SET_BATTLER_TYPE(gBattlerTarget, moveType); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); gBattlescriptCurrInstr = cmd->nextInstr; } return; @@ -10419,7 +10483,7 @@ static void Cmd_various(void) case VARIOUS_SET_ARG_TO_BATTLE_DAMAGE: { VARIOUS_ARGS(); - gBattleStruct->moveDamage[gBattlerTarget] = gMovesInfo[gCurrentMove].argument; + gBattleStruct->moveDamage[gBattlerTarget] = GetMoveFixedDamage(gCurrentMove); break; } case VARIOUS_TRY_AUTOTOMIZE: @@ -10441,8 +10505,8 @@ static void Cmd_various(void) VARIOUS_ARGS(const u8 *failInstr); u16 move = gLastPrintedMoves[gBattlerTarget]; if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE) - || gMovesInfo[move].instructBanned - || gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect + || IsMoveInstructBanned(move) + || gBattleMoveEffects[GetMoveEffect(move)].twoTurnEffect || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) || IsZMove(move) || IsMaxMove(move)) @@ -10624,6 +10688,7 @@ static void Cmd_various(void) { gBattlerSpriteIds[BATTLE_PARTNER(battler)] = gBattleScripting.savedDmg >> 8; gBattlerSpriteIds[battler] = gBattleScripting.savedDmg & 0xFF; + gBattleScripting.savedDmg = 0; if (IsBattlerAlive(battler)) { SetBattlerShadowSpriteCallback(battler, gBattleMons[battler].species); @@ -10691,14 +10756,15 @@ static void Cmd_various(void) case VARIOUS_TRY_THIRD_TYPE: { VARIOUS_ARGS(const u8 *failInstr); - if (IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument) || GetActiveGimmick(battler) == GIMMICK_TERA) + u32 type = GetMoveArgType(gCurrentMove); + if (IS_BATTLER_OF_TYPE(battler, type) || GetActiveGimmick(battler) == GIMMICK_TERA) { gBattlescriptCurrInstr = cmd->failInstr; } else { - gBattleMons[battler].types[2] = gMovesInfo[gCurrentMove].argument; - PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].argument); + gBattleMons[battler].types[2] = type; + PREPARE_TYPE_BUFFER(gBattleTextBuff1, type); gBattlescriptCurrInstr = cmd->nextInstr; } return; @@ -10807,53 +10873,6 @@ static void Cmd_various(void) MarkBattlerForControllerExec(battler); break; } - case VARIOUS_EERIE_SPELL_PP_REDUCE: - { - VARIOUS_ARGS(const u8 *failInstr); - if (gLastMoves[battler] != 0 && gLastMoves[battler] != 0xFFFF) - { - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gLastMoves[battler] == gBattleMons[battler].moves[i]) - break; - } - - if (i != MAX_MON_MOVES && gBattleMons[battler].pp[i] != 0) - { - s32 ppToDeduct = 3; - - if (gBattleMons[battler].pp[i] < ppToDeduct) - ppToDeduct = gBattleMons[battler].pp[i]; - - PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[battler]) - ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1); - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) - gBattleMons[battler].pp[i] -= ppToDeduct; - if (!(gDisableStructs[battler].mimickedMoves & (1u << i)) - && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) - { - BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[battler].pp[i]), &gBattleMons[battler].pp[i]); - MarkBattlerForControllerExec(battler); - } - - if (gBattleMons[battler].pp[i] == 0 && gBattleStruct->skyDropTargets[battler] == 0xFF) - CancelMultiTurnMoves(battler); - - gBattlescriptCurrInstr = cmd->nextInstr; // continue - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp - } - } - else - { - gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp - } - return; - } case VARIOUS_JUMP_IF_TEAM_HEALTHY: { VARIOUS_ARGS(const u8 *jumpInstr); @@ -11344,9 +11363,10 @@ static void Cmd_various(void) static void TryResetProtectUseCounter(u32 battler) { u32 lastMove = gLastResultingMoves[battler]; + u32 lastEffect = GetMoveEffect(lastMove); if (lastMove == MOVE_UNAVAILABLE - || (!gBattleMoveEffects[gMovesInfo[lastMove].effect].usesProtectCounter - && (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && gMovesInfo[lastMove].effect != EFFECT_ALLY_SWITCH))) + || (!gBattleMoveEffects[lastEffect].usesProtectCounter + && (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && lastEffect != EFFECT_ALLY_SWITCH))) gDisableStructs[battler].protectUses = 0; } @@ -11365,9 +11385,9 @@ static void Cmd_setprotectlike(void) || (gCurrentMove == MOVE_WIDE_GUARD && B_WIDE_GUARD != GEN_5) || (gCurrentMove == MOVE_QUICK_GUARD && B_QUICK_GUARD != GEN_5)) { - if (!gMovesInfo[gCurrentMove].argument) // Protects one mon only. + if (!GetMoveProtectSide(gCurrentMove)) // Protects one mon only. { - if (gMovesInfo[gCurrentMove].effect == EFFECT_ENDURE) + if (GetMoveEffect(gCurrentMove) == EFFECT_ENDURE) { gProtectStructs[gBattlerAttacker].endured = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BRACED_ITSELF; @@ -11530,7 +11550,7 @@ static void SetMoveForMirrorMove(u32 move) { gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; // Edge case, we used Z Mirror Move, got the stat boost and now need to use the Z-move - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move)) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move)) { gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move; gCurrentMove = GetTypeBasedZMove(move); @@ -11541,8 +11561,8 @@ static void SetMoveForMirrorMove(u32 move) } SetAtkCancellerForCalledMove(); - gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); - gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove); + gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove); } static void Cmd_trymirrormove(void) @@ -11922,10 +11942,7 @@ static void Cmd_setdrainedhp(void) { CMD_ARGS(); - if (gMovesInfo[gCurrentMove].argument != 0) - gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt * gMovesInfo[gCurrentMove].argument / 100); - else - gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt / 2); + gBattleStruct->moveDamage[gBattlerAttacker] = (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100); if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) gBattleStruct->moveDamage[gBattlerAttacker] = 1; @@ -12343,7 +12360,7 @@ static void Cmd_twoturnmoveschargestringandanimation(void) { CMD_ARGS(const u8 *animationThenStringPtr); - gBattleScripting.savedStringId = LOHALF(gMovesInfo[gCurrentMove].argument); + gBattleScripting.savedStringId = GetMoveTwoTurnAttackStringId(gCurrentMove); if (B_UPDATED_MOVE_DATA < GEN_5 || MoveHasChargeTurnAdditionalEffect(gCurrentMove)) gBattlescriptCurrInstr = cmd->animationThenStringPtr; else @@ -12572,7 +12589,7 @@ static void Cmd_tryconversiontypechange(void) { if (gBattleMons[gBattlerAttacker].moves[moveChecked] != MOVE_NONE) { - moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type; + moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]); break; } } @@ -12600,7 +12617,7 @@ static void Cmd_tryconversiontypechange(void) for (moveChecked = 0; moveChecked < validMoves; moveChecked++) { - moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type; + moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]); if (moveType == TYPE_MYSTERY) { @@ -12627,7 +12644,7 @@ static void Cmd_tryconversiontypechange(void) { while ((moveChecked = MOD(Random(), MAX_MON_MOVES)) >= validMoves); - moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type; + moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]); if (moveType == TYPE_MYSTERY) { @@ -12743,7 +12760,7 @@ static void Cmd_tryKO(void) } else { - u16 odds = gMovesInfo[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level); + u16 odds = GetMoveAccuracy(gCurrentMove) + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level); if (B_SHEER_COLD_ACC >= GEN_7 && gCurrentMove == MOVE_SHEER_COLD && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ICE)) odds -= 10; if (RandomPercentage(RNG_ACCURACY, odds) && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level) @@ -12906,14 +12923,15 @@ static void Cmd_setfocusenergy(void) { CMD_ARGS(u8 battler); u8 battler = GetBattlerForBattleScript(cmd->battler); + u32 effect = GetMoveEffect(gCurrentMove); - if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler)))) + if ((effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler)))) || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) { gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FOCUS_ENERGY_FAILED; } - else if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(battler, TYPE_DRAGON)) + else if (effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(battler, TYPE_DRAGON)) { gBattleMons[battler].status2 |= STATUS2_DRAGON_CHEER; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED; @@ -12967,8 +12985,9 @@ static void Cmd_transformdataexecution(void) gBattleStruct->overwrittenAbilities[gBattlerAttacker] = GetBattlerAbility(gBattlerTarget); for (i = 0; i < MAX_MON_MOVES; i++) { - if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].pp < 5) - gBattleMons[gBattlerAttacker].pp[i] = gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].pp; + u32 pp = GetMovePP(gBattleMons[gBattlerAttacker].moves[i]); + if (pp < 5) + gBattleMons[gBattlerAttacker].pp[i] = pp; else gBattleMons[gBattlerAttacker].pp[i] = 5; } @@ -12987,7 +13006,7 @@ static void Cmd_setsubstitute(void) { CMD_ARGS(); - u32 factor = gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL ? 2 : 4; + u32 factor = GetMoveEffect(gCurrentMove) == EFFECT_SHED_TAIL ? 2 : 4; u32 hp; if (factor == 2) @@ -13026,7 +13045,7 @@ static void Cmd_mimicattackcopy(void) { CMD_ARGS(const u8 *failInstr); - if ((gMovesInfo[gLastMoves[gBattlerTarget]].mimicBanned) + if ((IsMoveMimicBanned(gLastMoves[gBattlerTarget])) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) || gLastMoves[gBattlerTarget] == MOVE_NONE || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE) @@ -13047,8 +13066,9 @@ static void Cmd_mimicattackcopy(void) { gChosenMove = 0xFFFF; gBattleMons[gBattlerAttacker].moves[gCurrMovePos] = gLastMoves[gBattlerTarget]; - if (gMovesInfo[gLastMoves[gBattlerTarget]].pp < 5) - gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = gMovesInfo[gLastMoves[gBattlerTarget]].pp; + u32 pp = GetMovePP(gLastMoves[gBattlerTarget]); + if (pp < 5) + gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = pp; else gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = 5; @@ -13066,8 +13086,8 @@ static void Cmd_mimicattackcopy(void) static bool32 InvalidMetronomeMove(u32 move) { - return gMovesInfo[move].effect == EFFECT_PLACEHOLDER - || gMovesInfo[move].metronomeBanned; + return GetMoveEffect(move) == EFFECT_PLACEHOLDER + || IsMoveMetronomeBanned(move); } static void Cmd_metronome(void) @@ -13097,8 +13117,8 @@ static void Cmd_metronome(void) gCurrentMove = RandomUniformExcept(RNG_METRONOME, 1, moveCount - 1, InvalidMetronomeMove); SetAtkCancellerForCalledMove(); PrepareStringBattle(STRINGID_WAGGLINGAFINGER, gBattlerAttacker); - gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove); - gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove); + gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); } static void Cmd_dmgtolevel(void) @@ -13225,7 +13245,7 @@ static void Cmd_trysetencore(void) } } - if ((gMovesInfo[gLastMoves[gBattlerTarget]].encoreBanned) + if ((IsMoveEncoreBanned(gLastMoves[gBattlerTarget])) || gLastMoves[gBattlerTarget] == MOVE_NONE || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE) { @@ -13284,7 +13304,7 @@ static void Cmd_settypetorandomresistance(void) { gBattlescriptCurrInstr = cmd->failInstr; } - else if (gBattleMoveEffects[gMovesInfo[gLastLandedMoves[gBattlerAttacker]].effect].twoTurnEffect + else if (gBattleMoveEffects[GetMoveEffect(gLastLandedMoves[gBattlerAttacker])].twoTurnEffect && gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS) { gBattlescriptCurrInstr = cmd->failInstr; @@ -13413,7 +13433,7 @@ static void Cmd_copymovepermanently(void) if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) && gLastPrintedMoves[gBattlerTarget] != MOVE_UNAVAILABLE - && !gMovesInfo[gLastPrintedMoves[gBattlerTarget]].sketchBanned) + && !IsMoveSketchBanned(gLastPrintedMoves[gBattlerTarget])) { s32 i; @@ -13434,7 +13454,7 @@ static void Cmd_copymovepermanently(void) struct MovePpInfo movePpData; gBattleMons[gBattlerAttacker].moves[gCurrMovePos] = gLastPrintedMoves[gBattlerTarget]; - gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = gMovesInfo[gLastPrintedMoves[gBattlerTarget]].pp; + gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = GetMovePP(gLastPrintedMoves[gBattlerTarget]); for (i = 0; i < MAX_MON_MOVES; i++) { @@ -13465,8 +13485,8 @@ static void Cmd_trychoosesleeptalkmove(void) for (i = 0; i < MAX_MON_MOVES; i++) { - if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].sleepTalkBanned - || gBattleMoveEffects[gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].effect].twoTurnEffect) + if (IsMoveSleepTalkBanned(gBattleMons[gBattlerAttacker].moves[i]) + || gBattleMoveEffects[GetMoveEffect(gBattleMons[gBattlerAttacker].moves[i])].twoTurnEffect) { unusableMovesBits |= (1 << (i)); } @@ -13486,7 +13506,7 @@ static void Cmd_trychoosesleeptalkmove(void) movePosition = MOD(Random(), MAX_MON_MOVES); } while ((1u << movePosition) & unusableMovesBits); - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[movePosition])) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gBattleMons[gBattlerAttacker].moves[movePosition])) { gBattleStruct->zmove.baseMoves[gBattlerAttacker] = gBattleMons[gBattlerAttacker].moves[movePosition]; gCalledMove = GetTypeBasedZMove(gBattleMons[gBattlerAttacker].moves[movePosition]); @@ -13497,7 +13517,7 @@ static void Cmd_trychoosesleeptalkmove(void) } gCurrMovePos = movePosition; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gBattlescriptCurrInstr = cmd->failInstr; } } @@ -13586,7 +13606,7 @@ static void Cmd_tryspiteppreduce(void) { s32 ppToDeduct = B_PP_REDUCED_BY_SPITE >= GEN_4 ? 4 : (Random() & 3) + 2; // G-Max Depletion only deducts 2 PP. - if (IsMaxMove(gCurrentMove) && gMovesInfo[gCurrentMove].argument == MAX_EFFECT_SPITE) + if (IsMaxMove(gCurrentMove) && GetMoveMaxEffect(gCurrentMove) == MAX_EFFECT_SPITE) ppToDeduct = 2; if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct) @@ -14030,7 +14050,7 @@ static bool32 SetTargetToNextPursuiter(u32 battlerDef) { u32 battler = gBattlerByTurnOrder[i]; if (gChosenActionByBattler[battler] == B_ACTION_USE_MOVE - && gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT + && GetMoveEffect(gChosenMoveByBattler[battler]) == EFFECT_PURSUIT && IsBattlerAlive(battlerDef) && IsBattlerAlive(battler) && GetBattlerSide(battler) != GetBattlerSide(battlerDef) @@ -14311,7 +14331,7 @@ static void Cmd_trydobeatup(void) gBattlescriptCurrInstr = cmd->nextInstr; gBattleStruct->moveDamage[gBattlerTarget] = gSpeciesInfo[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; - gBattleStruct->moveDamage[gBattlerTarget] *= gMovesInfo[gCurrentMove].power; + gBattleStruct->moveDamage[gBattlerTarget] *= GetMovePower(gCurrentMove); gBattleStruct->moveDamage[gBattlerTarget] *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); gBattleStruct->moveDamage[gBattlerTarget] /= gSpeciesInfo[gBattleMons[gBattlerTarget].species].baseDefense; gBattleStruct->moveDamage[gBattlerTarget] = (gBattleStruct->moveDamage[gBattlerTarget] / 50) + 2; @@ -14336,9 +14356,9 @@ static void Cmd_setsemiinvulnerablebit(void) { CMD_ARGS(bool8 clear); - if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE) + if (gBattleMoveEffects[GetMoveEffect(gCurrentMove)].semiInvulnerableEffect == TRUE) { - u32 semiInvulnerableEffect = UNCOMPRESS_BITS(HIHALF(gMovesInfo[gCurrentMove].argument)); + u32 semiInvulnerableEffect = GetMoveTwoTurnAttackStatus(gCurrentMove); if (cmd->clear) gStatuses3[gBattlerAttacker] &= ~semiInvulnerableEffect; else @@ -14351,7 +14371,7 @@ static void Cmd_setsemiinvulnerablebit(void) static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffects) { // Semi-invulnerable moves cannot skip their charge turn (except with Power Herb) - if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE) + if (gBattleMoveEffects[GetMoveEffect(gCurrentMove)].semiInvulnerableEffect == TRUE) return FALSE; // If this move has charge turn effects, it must charge, activate them, then try to fire @@ -14362,7 +14382,7 @@ static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffe // Certain two-turn moves may fire on the first turn in the right weather (Solar Beam, Electro Shot) // By default, all two-turn moves have the option of adding weather to their argument - if (IsBattlerWeatherAffected(battler, HIHALF(gMovesInfo[gCurrentMove].argument))) + if (IsBattlerWeatherAffected(battler, GetMoveTwoTurnAttackWeather(gCurrentMove))) return TRUE; return FALSE; @@ -14433,7 +14453,7 @@ static void Cmd_setforcedtarget(void) gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 1; gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget = gBattlerTarget; - gSideTimers[GetBattlerSide(gBattlerTarget)].followmePowder = gMovesInfo[gCurrentMove].powderMove; + gSideTimers[GetBattlerSide(gBattlerTarget)].followmePowder = IsPowderMove(gCurrentMove); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -14458,8 +14478,8 @@ static void Cmd_callterrainattack(void) gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gCurrentMove = GetNaturePowerMove(gBattlerAttacker); - gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); - BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove)); + gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + BattleScriptPush(GetMoveBattleScript(gCurrentMove)); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -14491,7 +14511,7 @@ static void Cmd_curestatuswithmove(void) CMD_ARGS(const u8 *failInstr); u32 shouldHeal; - if (gMovesInfo[gCurrentMove].effect == EFFECT_REFRESH) + if (GetMoveEffect(gCurrentMove) == EFFECT_REFRESH) shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_REFRESH; else // Take Heart shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY; @@ -14716,7 +14736,7 @@ static void Cmd_trycopyability(void) if (gBattleMons[battler].ability == defAbility || defAbility == ABILITY_NONE || gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed - || (IsBattlerAlive(BATTLE_PARTNER(battler)) && gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed && gMovesInfo[gCurrentMove].effect == EFFECT_DOODLE) + || (IsBattlerAlive(BATTLE_PARTNER(battler)) && gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed && GetMoveEffect(gCurrentMove) == EFFECT_DOODLE) || gAbilitiesInfo[defAbility].cantBeCopied) { gBattlescriptCurrInstr = cmd->failInstr; @@ -14870,7 +14890,7 @@ static void Cmd_setroom(void) { CMD_ARGS(); - switch (gMovesInfo[gCurrentMove].effect) + switch (GetMoveEffect(gCurrentMove)) { case EFFECT_TRICK_ROOM: HandleRoomMove(STATUS_FIELD_TRICK_ROOM, &gFieldTimers.trickRoomTimer, 0); @@ -15035,7 +15055,7 @@ static void Cmd_assistattackselect(void) { u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); - if (gMovesInfo[move].assistBanned) + if (IsMoveAssistBanned(move)) continue; validMoves[chooseableMovesNo++] = move; @@ -15047,7 +15067,7 @@ static void Cmd_assistattackselect(void) { gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gCalledMove = validMoves[Random() % chooseableMovesNo]; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -15121,10 +15141,10 @@ static void Cmd_switchoutabilities(void) break; case ABILITY_REGENERATOR: { - u32 regenerate = GetNonDynamaxMaxHP(gBattlerAttacker) / 3; + u32 regenerate = GetNonDynamaxMaxHP(battler) / 3; regenerate += gBattleMons[battler].hp; - if (gBattleStruct->moveDamage[gBattlerAttacker] > gBattleMons[battler].maxHP) - gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[battler].maxHP; + if (regenerate > gBattleMons[battler].maxHP) + regenerate = gBattleMons[battler].maxHP; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HP_BATTLE, 1u << *(gBattleStruct->battlerPartyIndexes + battler), sizeof(regenerate), @@ -15156,8 +15176,9 @@ static void Cmd_jumpifnotcurrentmoveargtype(void) u8 battler = GetBattlerForBattleScript(cmd->battler); const u8 *failInstr = cmd->failInstr; + u32 type = GetMoveArgType(gCurrentMove); - if (!IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument)) + if (!IS_BATTLER_OF_TYPE(battler, type)) gBattlescriptCurrInstr = failInstr; else gBattlescriptCurrInstr = cmd->nextInstr; @@ -15251,7 +15272,7 @@ static void Cmd_settypebasedhalvers(void) bool8 worked = FALSE; - if (gMovesInfo[gCurrentMove].effect == EFFECT_MUD_SPORT) + if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT) { if (B_SPORT_TURNS >= GEN_6) { @@ -15306,7 +15327,7 @@ bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move) { if (!(gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE)) return FALSE; - else if (gMovesInfo[move].ignoresSubstitute) + else if (MoveIgnoresSubstitute(move)) return FALSE; else if (GetBattlerAbility(battlerAtk) == ABILITY_INFILTRATOR) return FALSE; @@ -15318,7 +15339,7 @@ bool32 DoesDisguiseBlockMove(u32 battler, u32 move) { if (!(gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED) || gBattleMons[battler].status2 & STATUS2_TRANSFORMED - || (!gProtectStructs[battler].confusionSelfDmg && (IS_MOVE_STATUS(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE)) + || (!gProtectStructs[battler].confusionSelfDmg && (IsBattleMoveStatus(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE)) || gHitMarker & HITMARKER_IGNORE_DISGUISE || GetBattlerAbility(battler) != ABILITY_DISGUISE) return FALSE; @@ -15417,7 +15438,7 @@ static void Cmd_pursuitdoubles(void) if (IsDoubleBattle() && !(gAbsentBattlerFlags & (1u << battler)) && gChosenActionByBattler[battler] == B_ACTION_USE_MOVE - && gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT) + && GetMoveEffect(gChosenMoveByBattler[battler]) == EFFECT_PURSUIT) { gActionsByTurnOrder[battler] = B_ACTION_TRY_FINISH; gCurrentMove = gChosenMoveByBattler[battler]; @@ -16427,10 +16448,10 @@ static bool32 CriticalCapture(u32 odds) bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler) { if (move != MOVE_NONE && move != MOVE_UNAVAILABLE && move != MOVE_STRUGGLE - && !gMovesInfo[move].parentalBondBanned - && gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS - && gMovesInfo[move].strikeCount < 2 - && gMovesInfo[move].effect != EFFECT_MULTI_HIT) + && !IsMoveParentalBondBanned(move) + && GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS + && GetMoveStrikeCount(move) < 2 + && GetMoveEffect(move) != EFFECT_MULTI_HIT) { if (IsDoubleBattle()) { @@ -16485,9 +16506,11 @@ static bool8 CanBurnHitThaw(u16 move) if (B_BURN_HIT_THAW >= GEN_6) { - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].moveEffect == MOVE_EFFECT_BURN) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + if (additionalEffect->moveEffect == MOVE_EFFECT_BURN) return TRUE; } } @@ -16925,11 +16948,11 @@ void BS_ApplySaltCure(void) gBattlescriptCurrInstr = cmd->nextInstr; } -void BS_JumpIfArgument(void) +void BS_JumpIfMovePropertyArgument(void) { NATIVE_ARGS(u8 argument, const u8 *jumpInstr); - if (gMovesInfo[gCurrentMove].argument == cmd->argument) + if (GetMoveEffectArg_MoveProperty(gCurrentMove) == cmd->argument) gBattlescriptCurrInstr = cmd->jumpInstr; else gBattlescriptCurrInstr = cmd->nextInstr; @@ -16940,7 +16963,7 @@ void BS_SetRemoveTerrain(void) NATIVE_ARGS(const u8 *jumpInstr); u32 statusFlag = 0; - switch (gMovesInfo[gCurrentMove].effect) + switch (GetMoveEffect(gCurrentMove)) { case EFFECT_MISTY_TERRAIN: statusFlag = STATUS_FIELD_MISTY_TERRAIN; @@ -16959,7 +16982,7 @@ void BS_SetRemoveTerrain(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; break; case EFFECT_HIT_SET_REMOVE_TERRAIN: - switch (gMovesInfo[gCurrentMove].argument) + switch (GetMoveEffectArg_MoveProperty(gCurrentMove)) { case ARG_SET_PSYCHIC_TERRAIN: // Genesis Supernova statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; @@ -16993,7 +17016,7 @@ void BS_SetRemoveTerrain(void) { u32 atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE); - gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; gFieldStatuses |= statusFlag; gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5; gBattlescriptCurrInstr = cmd->nextInstr; @@ -17148,7 +17171,7 @@ void BS_SetPledge(void) && GetBattlerTurnOrderNum(gBattlerAttacker) < GetBattlerTurnOrderNum(partner) && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gCurrentMove != partnerMove - && gMovesInfo[partnerMove].effect == EFFECT_PLEDGE) + && GetMoveEffect(partnerMove) == EFFECT_PLEDGE) { u32 currPledgeUser = 0; u32 newTurnOrder[] = {0xFF, 0xFF}; @@ -17274,9 +17297,9 @@ void BS_TryHealPulse(void) } else { - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && gMovesInfo[gCurrentMove].pulseMove) + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && IsPulseMove(gCurrentMove)) gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100); - else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_FLORAL_HEALING) + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_FLORAL_HEALING) gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3); else gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) / 2); @@ -17291,13 +17314,13 @@ void BS_TryCopycat(void) { NATIVE_ARGS(const u8 *failInstr); - if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned || IsZMove(gLastUsedMove)) + if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || IsMoveCopycatBanned(gLastUsedMove) || IsZMove(gLastUsedMove)) { gBattlescriptCurrInstr = cmd->failInstr; } else { - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gLastUsedMove)) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gLastUsedMove)) { gBattleStruct->zmove.baseMoves[gBattlerAttacker] = gLastUsedMove; gCalledMove = GetTypeBasedZMove(gLastUsedMove); @@ -17312,7 +17335,7 @@ void BS_TryCopycat(void) } gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -17343,7 +17366,7 @@ void BS_TryUpperHand(void) if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) || gChosenMoveByBattler[gBattlerTarget] == MOVE_NONE - || IS_MOVE_STATUS(gChosenMoveByBattler[gBattlerTarget]) + || IsBattleMoveStatus(gChosenMoveByBattler[gBattlerTarget]) || GetChosenMovePriority(gBattlerTarget) < 1 || GetChosenMovePriority(gBattlerTarget) > 3) // Fails if priority is less than 1 or greater than 3, if target already moved, or if using a status gBattlescriptCurrInstr = cmd->failInstr; else @@ -17397,9 +17420,10 @@ void BS_AllySwitchFailChance(void) void BS_SetPhotonGeyserCategory(void) { NATIVE_ARGS(); - if (!((gMovesInfo[gCurrentMove].effect == EFFECT_TERA_BLAST && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA) - || (gMovesInfo[gCurrentMove].effect == EFFECT_TERA_STARSTORM && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR))) - gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != gMovesInfo[gCurrentMove].category); + u32 effect = GetMoveEffect(gCurrentMove); + if (!((effect == EFFECT_TERA_BLAST && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA) + || (effect == EFFECT_TERA_STARSTORM && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR))) + gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != GetMoveCategory(gCurrentMove)); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -17706,7 +17730,7 @@ void BS_JumpIfBlockedBySoundproof(void) { NATIVE_ARGS(u8 battler, const u8 *jumpInstr); u32 battler = GetBattlerForBattleScript(cmd->battler); - if (gMovesInfo[gCurrentMove].soundMove && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF) + if (IsSoundMove(gCurrentMove) && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF) { gLastUsedAbility = ABILITY_SOUNDPROOF; gBattlescriptCurrInstr = cmd->jumpInstr; diff --git a/src/battle_tower.c b/src/battle_tower.c index 6f80823b98..9eda82f1b5 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -1590,7 +1590,7 @@ void CreateFacilityMon(const struct TrainerMon *fmon, u16 level, u8 fixedIV, u32 move = MOVE_FRUSTRATION; SetMonMoveSlot(dst, move, j); - if (gMovesInfo[move].effect == EFFECT_FRUSTRATION) + if (GetMoveEffect(move) == EFFECT_FRUSTRATION) friendship = 0; // Frustration is more powerful the lower the pokemon's friendship is. } @@ -1758,39 +1758,6 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) } } -// Probably an early draft before the 'CreateApprenticeMon' was written. -static void UNUSED Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) -{ - s32 i, j; - u8 friendship = MAX_FRIENDSHIP; - u8 level = 0; - u8 fixedIV = 0; - struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[0]; - - if (apprentice->numQuestions < 5) - fixedIV = 6; - else - fixedIV = 9; - - if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50) - level = FRONTIER_MAX_LEVEL_OPEN; - else - level = FRONTIER_MAX_LEVEL_50; - - for (i = 0; i != FRONTIER_PARTY_SIZE; i++) - { - CreateMonWithEVSpread(&gEnemyParty[firstMonId + i], apprentice->party[i].species, level, fixedIV, 8); - friendship = MAX_FRIENDSHIP; - for (j = 0; j < MAX_MON_MOVES; j++) - { - if (gMovesInfo[apprentice->party[i].moves[j]].effect == EFFECT_FRUSTRATION) - friendship = 0; - } - SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship); - SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &apprentice->party[i].item); - } -} - u16 GetRandomFrontierMonFromSet(u16 trainerId) { u8 level = SetFacilityPtrsGetLevel(); diff --git a/src/battle_tv.c b/src/battle_tv.c index b03eee1ca9..e5be946d81 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -774,7 +774,7 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc tvPtr->side[atkSide].wishMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; tvPtr->side[atkSide].wishMoveSlot = moveSlot; } - if (gMovesInfo[move].effect == EFFECT_EXPLOSION) + if (GetMoveEffect(move) == EFFECT_EXPLOSION) { tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1; tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot = moveSlot; @@ -782,10 +782,11 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc tvPtr->side[atkSide ^ BIT_SIDE].explosion = TRUE; } - AddMovePoints(PTS_REFLECT, move, gMovesInfo[move].power, 0); - AddMovePoints(PTS_LIGHT_SCREEN, move, gMovesInfo[move].power, 0); - AddMovePoints(PTS_WATER_SPORT, move, 0, 0); - AddMovePoints(PTS_MUD_SPORT, move, 0, 0); + u32 movePower = GetMovePower(move); + AddMovePoints(PTS_REFLECT, move, movePower, 0); + AddMovePoints(PTS_LIGHT_SCREEN, move, movePower, 0); + AddMovePoints(PTS_WATER_SPORT, move, 0, 0); + AddMovePoints(PTS_MUD_SPORT, move, 0, 0); } void BattleTv_SetDataBasedOnAnimation(u8 animationId) @@ -928,10 +929,10 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) { case PTS_MOVE_EFFECT: // arg1 -> move slot, arg2 -> move { - u8 baseFromEffect = gBattleMoveEffects[gMovesInfo[arg2].effect].battleTvScore; + u8 baseFromEffect = gBattleMoveEffects[GetMoveEffect(arg2)].battleTvScore; // Various cases to add/remove points - if (gMovesInfo[arg2].recoil > 0) + if (GetMoveRecoil(arg2) > 0) baseFromEffect++; // Recoil moves if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_RAPID_SPIN)) baseFromEffect++; @@ -1006,7 +1007,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) #define power arg2 case PTS_WATER_SPORT: // If used fire move during Water Sport - if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && gMovesInfo[move].type == TYPE_FIRE) + if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && GetMoveType(move) == TYPE_FIRE) { if (tvPtr->pos[defSide][0].waterSportMonId != 0) { @@ -1022,7 +1023,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) break; case PTS_MUD_SPORT: // If used Electric move during Mud Sport - if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && gMovesInfo[move].type == TYPE_ELECTRIC) + if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && GetMoveType(move) == TYPE_ELECTRIC) { if (tvPtr->pos[defSide][0].mudSportMonId != 0) { @@ -1038,7 +1039,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) break; case PTS_REFLECT: // If hit Reflect with damaging physical move - if (IS_MOVE_PHYSICAL(move) && power != 0 && tvPtr->side[defSide].reflectMonId != 0) + if (IsBattleMovePhysical(move) && power != 0 && tvPtr->side[defSide].reflectMonId != 0) { u32 id = (tvPtr->side[defSide].reflectMonId - 1) * 4; movePoints->points[defSide][id + tvPtr->side[defSide].reflectMoveSlot] += sPointsArray[caseId][0]; @@ -1046,7 +1047,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) break; case PTS_LIGHT_SCREEN: // If hit Light Screen with damaging special move - if (IS_MOVE_SPECIAL(move) && power != 0 && tvPtr->side[defSide].lightScreenMonId != 0) + if (IsBattleMoveSpecial(move) && power != 0 && tvPtr->side[defSide].lightScreenMonId != 0) { u32 id = (tvPtr->side[defSide].lightScreenMonId - 1) * 4; movePoints->points[defSide][id + tvPtr->side[defSide].lightScreenMoveSlot] += sPointsArray[caseId][0]; @@ -1227,7 +1228,7 @@ static void TrySetBattleSeminarShow(void) return; else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID)) return; - else if (IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]])) + else if (IsBattleMoveStatus(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]])) return; i = 0; @@ -1254,7 +1255,7 @@ static void TrySetBattleSeminarShow(void) damageCalcData.battlerAtk = gBattlerAttacker; damageCalcData.battlerDef = gBattlerTarget; damageCalcData.move = gCurrentMove; - damageCalcData.moveType = gMovesInfo[gCurrentMove].type; + damageCalcData.moveType = GetMoveType(gCurrentMove); damageCalcData.isCrit = FALSE; damageCalcData.randomFactor = FALSE; damageCalcData.updateFlags = FALSE; @@ -1296,7 +1297,7 @@ static void TrySetBattleSeminarShow(void) static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride) { - if (IS_MOVE_STATUS(moveId)) + if (IsBattleMoveStatus(moveId)) { *dmg = 0; return FALSE; diff --git a/src/battle_util.c b/src/battle_util.c index f43f285e93..fd264e4606 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -56,6 +56,7 @@ match the ROM; this is also why sSoundMovesTable's declaration is in the middle functions instead of at the top of the file with the other declarations. */ +typedef void (*MoveSuccessOrderCancellers)(u32 *effect); static bool32 TryRemoveScreens(u32 battler); static bool32 IsUnnerveAbilityOnOpposingSide(u32 battler); static u32 GetFlingPowerFromItemId(u32 itemId); @@ -111,15 +112,15 @@ static u8 CalcBeatUpPower(void) bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move) { u32 ability = GetBattlerAbility(battlerAtk); + u32 effect = GetMoveEffect(move); if (gSideTimers[defSide].followmeTimer == 0 || !IsBattlerAlive(gSideTimers[defSide].followmeTarget) - || gMovesInfo[move].effect == EFFECT_SNIPE_SHOT - || gMovesInfo[move].effect == EFFECT_SKY_DROP + || effect == EFFECT_SNIPE_SHOT || effect == EFFECT_SKY_DROP || ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART) return FALSE; - if (gMovesInfo[move].effect == EFFECT_PURSUIT && gBattleStruct->pursuitTarget) + if (effect == EFFECT_PURSUIT && gBattleStruct->pursuitTarget) return FALSE; if (gSideTimers[defSide].followmePowder && !IsAffectedByPowder(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE))) @@ -157,7 +158,7 @@ void HandleAction_UseMove(void) gProtectStructs[gBattlerAttacker].noValidMoves = FALSE; gCurrentMove = gChosenMove = MOVE_STRUGGLE; gHitMarker |= HITMARKER_NO_PPDEDUCT; - *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE); + *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE); } else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) { @@ -169,7 +170,7 @@ void HandleAction_UseMove(void) { gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove; gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos; - *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); } // check if the encored move wasn't overwritten else if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE @@ -180,12 +181,12 @@ void HandleAction_UseMove(void) gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE; gDisableStructs[gBattlerAttacker].encoredMovePos = 0; gDisableStructs[gBattlerAttacker].encoreTimer = 0; - *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); } else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMoveByBattler[gBattlerAttacker]) { gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); + *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); } else { @@ -202,22 +203,23 @@ void HandleAction_UseMove(void) // Set dynamic move type. SetTypeBeforeUsingMove(gChosenMove, gBattlerAttacker); - moveType = GetMoveType(gCurrentMove); + moveType = GetBattleMoveType(gCurrentMove); // check Z-Move used - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gCurrentMove) && !IsZMove(gCurrentMove)) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gCurrentMove) && !IsZMove(gCurrentMove)) { - gBattleStruct->categoryOverride = gMovesInfo[gCurrentMove].category; + gBattleStruct->categoryOverride = GetMoveCategory(gCurrentMove); gCurrentMove = gChosenMove = GetUsableZMove(gBattlerAttacker, gCurrentMove); } // check Max Move used else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX) { - gBattleStruct->categoryOverride = gMovesInfo[gCurrentMove].category; + gBattleStruct->categoryOverride = GetMoveCategory(gCurrentMove); gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove); } moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); + u32 moveEffect = GetMoveEffect(gCurrentMove); // choose target side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)); @@ -230,7 +232,7 @@ void HandleAction_UseMove(void) else if (IsDoubleBattle() && gSideTimers[side].followmeTimer == 0 && !(gBattleStruct->pursuitTarget & (1u << *(gBattleStruct->moveTarget + gBattlerAttacker))) - && (!IS_MOVE_STATUS(gCurrentMove) || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS)) + && (!IsBattleMoveStatus(gCurrentMove) || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS)) && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) || (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) { @@ -242,8 +244,8 @@ void HandleAction_UseMove(void) && ((GetBattlerAbility(battler) == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) || (GetBattlerAbility(battler) == ABILITY_STORM_DRAIN && moveType == TYPE_WATER)) && GetBattlerTurnOrderNum(battler) < var - && gMovesInfo[gCurrentMove].effect != EFFECT_SNIPE_SHOT - && gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE + && moveEffect != EFFECT_SNIPE_SHOT + && moveEffect != EFFECT_PLEDGE && GetBattlerAbility(gBattlerAttacker) != ABILITY_PROPELLER_TAIL && GetBattlerAbility(gBattlerAttacker) != ABILITY_STALWART) { @@ -355,7 +357,7 @@ void HandleAction_UseMove(void) } else { - gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove); + gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove); } if (gBattleTypeFlags & BATTLE_TYPE_ARENA) @@ -690,11 +692,11 @@ void HandleAction_ActionFinished(void) | HITMARKER_CHARGING | HITMARKER_NEVER_SET | HITMARKER_IGNORE_DISGUISE); // check if Stellar type boost should be used up - moveType = GetMoveType(gCurrentMove); + moveType = GetBattleMoveType(gCurrentMove); if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA && GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR - && gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS + && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS && IsTypeStellarBoosted(gBattlerAttacker, moveType)) { ExpendTypeStellarBoost(gBattlerAttacker, moveType); @@ -1103,7 +1105,7 @@ static bool32 IsGravityPreventingMove(u32 move) if (!(gFieldStatuses & STATUS_FIELD_GRAVITY)) return FALSE; - return gMovesInfo[move].gravityBanned; + return IsMoveGravityBanned(move); } bool32 IsHealBlockPreventingMove(u32 battler, u32 move) @@ -1111,12 +1113,12 @@ bool32 IsHealBlockPreventingMove(u32 battler, u32 move) if (!(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) return FALSE; - return gMovesInfo[move].healingMove; + return IsHealingMove(move); } bool32 IsBelchPreventingMove(u32 battler, u32 move) { - if (gMovesInfo[move].effect != EFFECT_BELCH) + if (GetMoveEffect(move) != EFFECT_BELCH) return FALSE; return !(gBattleStruct->ateBerry[battler & BIT_SIDE] & (1u << gBattlerPartyIndexes[battler])); @@ -1132,6 +1134,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) u32 move = gBattleMons[battler].moves[moveId]; u32 holdEffect = GetBattlerHoldEffect(battler, TRUE); u16 *choicedMove = &gBattleStruct->choicedMove[battler]; + u32 moveEffect = GetMoveEffect(move); if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].disabledMove == move && move != MOVE_NONE) { @@ -1164,7 +1167,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) } } - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IS_MOVE_STATUS(move)) + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IsBattleMoveStatus(move)) { if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)) gCurrentMove = MOVE_MAX_GUARD; @@ -1182,7 +1185,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) } } - if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && gMovesInfo[move].soundMove) + if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && IsSoundMove(move)) { gCurrentMove = move; if (gBattleTypeFlags & BATTLE_TYPE_PALACE) @@ -1257,7 +1260,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) } } - if (DYNAMAX_BYPASS_CHECK && gMovesInfo[move].effect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES) + if (DYNAMAX_BYPASS_CHECK && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES) { gCurrentMove = move; if (gBattleTypeFlags & BATTLE_TYPE_PALACE) @@ -1272,7 +1275,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) } } - if (gMovesInfo[move].cantUseTwice && move == gLastResultingMoves[battler]) + if (MoveCantBeUsedTwice(move) && move == gLastResultingMoves[battler]) { gCurrentMove = move; PREPARE_MOVE_BUFFER(gBattleTextBuff1, gCurrentMove); @@ -1304,7 +1307,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) limitations++; } } - else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_ME_FIRST) + else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IsBattleMoveStatus(move) && moveEffect != EFFECT_ME_FIRST) { if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)) gCurrentMove = MOVE_MAX_GUARD; @@ -1352,7 +1355,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler) } } - if (gMovesInfo[move].effect == EFFECT_PLACEHOLDER) + if (moveEffect == EFFECT_PLACEHOLDER) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { @@ -1381,7 +1384,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) for (i = 0; i < MAX_MON_MOVES; i++) { move = gBattleMons[battler].moves[i]; - moveEffect = gMovesInfo[move].effect; + moveEffect = GetMoveEffect(move); // No move if (check & MOVE_LIMITATION_ZEROMOVE && move == MOVE_NONE) unusableMoves |= 1u << i; @@ -1398,7 +1401,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT) unusableMoves |= 1u << i; // Taunt - else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IS_MOVE_STATUS(move)) + else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IsBattleMoveStatus(move)) unusableMoves |= 1u << i; // Imprison else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, move)) @@ -1410,7 +1413,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move) unusableMoves |= 1u << i; // Assault Vest - else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_ME_FIRST) + else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IsBattleMoveStatus(move) && moveEffect != EFFECT_ME_FIRST) unusableMoves |= 1u << i; // Gravity else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(move)) @@ -1422,7 +1425,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battler, move)) unusableMoves |= 1u << i; // Throat Chop - else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && gMovesInfo[move].soundMove) + else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && IsSoundMove(move)) unusableMoves |= 1u << i; // Stuff Cheeks else if (check & MOVE_LIMITATION_STUFF_CHEEKS && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES) @@ -1431,7 +1434,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battler) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move) unusableMoves |= 1u << i; // Can't Use Twice flag - else if (check & MOVE_LIMITATION_CANT_USE_TWICE && gMovesInfo[move].cantUseTwice && move == gLastResultingMoves[battler]) + else if (check & MOVE_LIMITATION_CANT_USE_TWICE && MoveCantBeUsedTwice(move) && move == gLastResultingMoves[battler]) unusableMoves |= 1u << i; } return unusableMoves; @@ -1553,7 +1556,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId) { if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN) BattleScriptExecute(BattleScript_GrassyTerrainHeals); - if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0) + if (gFieldTimers.terrainTimer > 0 && --gFieldTimers.terrainTimer == 0) { gFieldStatuses &= ~terrainFlag; TryToRevertMimicryAndFlags(); @@ -3116,638 +3119,750 @@ void TryClearRageAndFuryCutter(void) } } +static inline bool32 TryFormChangeBeforeMove(void) +{ + bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE); + if (!result) + result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY); + if (!result) + return FALSE; + + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AttackerFormChange; + return TRUE; +} + void SetAtkCancellerForCalledMove(void) { gBattleStruct->atkCancellerTracker = CANCELLER_HEAL_BLOCKED; gBattleStruct->isAtkCancelerForCalledMove = TRUE; } -u8 AtkCanceller_UnableToUseMove(u32 moveType) +static void CancellerFlags(u32 *effect) { - u32 effect = 0; - u32 obedienceResult; - do + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; + gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; + gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH; +} + +static void CancellerStanceChangeOne(u32 *effect) +{ + if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove()) + *effect = 1; +} + +static void CancellerSkyDrop(u32 *effect) +{ + // If Pokemon is being held in Sky Drop + if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) { - switch (gBattleStruct->atkCancellerTracker) + gBattlescriptCurrInstr = BattleScript_MoveEnd; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerRecharge(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) + { + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RECHARGE; + gDisableStructs[gBattlerAttacker].rechargeTimer = 0; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerAsleep(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) + { + if (UproarWakeUpCheck(gBattlerAttacker)) { - case CANCELLER_FLAGS: // flags clear - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; - gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; - gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH; - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_SKY_DROP: - // If Pokemon is being held in Sky Drop - if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) - { - gBattlescriptCurrInstr = BattleScript_MoveEnd; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_ASLEEP: // check being asleep + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + *effect = 2; + } + else + { + u8 toSub; + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD) + toSub = 2; + else + toSub = 1; + if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) < toSub) + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; + else + gBattleMons[gBattlerAttacker].status1 -= toSub; if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) { - if (UproarWakeUpCheck(gBattlerAttacker)) + if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK) { - TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); - gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR; - gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; - effect = 2; - } - else - { - u8 toSub; - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD) - toSub = 2; - else - toSub = 1; - if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) < toSub) - gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; - else - gBattleMons[gBattlerAttacker].status1 -= toSub; - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) - { - if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK) - { - gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 2; - } - } - else - { - TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; - gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; - effect = 2; - } - } - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_FROZEN: // check being frozen - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !(gMovesInfo[gCurrentMove].thawsUser)) - { - if (!RandomPercentage(RNG_FROZEN, 20)) - { - gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; - gHitMarker |= (HITMARKER_NO_ATTACKSTRING | HITMARKER_UNABLE_TO_USE_MOVE); - } - else // unfreeze - { - gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED; - } - effect = 2; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_OBEDIENCE: - obedienceResult = GetAttackerObedienceForAction(); - if (obedienceResult != OBEYS - && !(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves - && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - switch (obedienceResult) - { - case DISOBEYS_LOAFS: - // Randomly select, then print a disobedient string - // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE - gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS); - gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; - gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - break; - case DISOBEYS_HITS_SELF: - gBattlerTarget = gBattlerAttacker; - struct DamageCalculationData damageCalcData; - damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; - damageCalcData.move = MOVE_NONE; - damageCalcData.moveType = TYPE_MYSTERY; - damageCalcData.isCrit = FALSE; - damageCalcData.randomFactor = FALSE; - damageCalcData.updateFlags = TRUE; - gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40); - gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself; + gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gHitMarker |= HITMARKER_OBEYS; - break; - case DISOBEYS_FALL_ASLEEP: - if (IsSleepClauseEnabled()) - gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; - gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - break; - case DISOBEYS_WHILE_ASLEEP: - gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep; - gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - break; - case DISOBEYS_RANDOM_MOVE: - gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - SetAtkCancellerForCalledMove(); - gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gHitMarker |= HITMARKER_DISOBEDIENT_MOVE; - gHitMarker |= HITMARKER_OBEYS; - break; + *effect = 2; } - effect = 1; } else { - gHitMarker |= HITMARKER_OBEYS; + TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]); + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + *effect = 2; } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_TRUANT: // truant - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) - { - CancelMultiTurnMoves(gBattlerAttacker); - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LOAFING; - gBattlerAbility = gBattlerAttacker; - gBattlescriptCurrInstr = BattleScript_TruantLoafingAround; - gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_RECHARGE: // recharge - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) - { - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RECHARGE; - gDisableStructs[gBattlerAttacker].rechargeTimer = 0; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_FLINCH: // flinch - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED) - { - gProtectStructs[gBattlerAttacker].flinchImmobility = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_DISABLED: // disabled move - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE) - { - gProtectStructs[gBattlerAttacker].usedDisabledMove = TRUE; - gBattleScripting.battler = gBattlerAttacker; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_HEAL_BLOCKED: - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove)) - { - gProtectStructs[gBattlerAttacker].usedHealBlockedMove = TRUE; - gBattleScripting.battler = gBattlerAttacker; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_GRAVITY: - if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove)) - { - gProtectStructs[gBattlerAttacker].usedGravityPreventedMove = TRUE; - gBattleScripting.battler = gBattlerAttacker; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_TAUNTED: // taunt - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IS_MOVE_STATUS(gCurrentMove)) - { - gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_IMPRISONED: // imprisoned - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove)) - { - gProtectStructs[gBattlerAttacker].usedImprisonedMove = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_CONFUSED: // confusion - if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) - { - if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION)) - gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1); - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) - { - // confusion dmg - if (RandomPercentage(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50))) - { - gBattleCommunication[MULTISTRING_CHOOSER] = TRUE; - gBattlerTarget = gBattlerAttacker; - struct DamageCalculationData damageCalcData; - damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; - damageCalcData.move = MOVE_NONE; - damageCalcData.moveType = TYPE_MYSTERY; - damageCalcData.isCrit = FALSE; - damageCalcData.randomFactor = FALSE; - damageCalcData.updateFlags = TRUE; - gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40); - gProtectStructs[gBattlerAttacker].confusionSelfDmg = TRUE; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = FALSE; - BattleScriptPushCursor(); - } - gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; - } - else // snapped out of confusion - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; - } - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_PARALYSED: // paralysis - if (!gBattleStruct->isAtkCancelerForCalledMove && (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && !RandomPercentage(RNG_PARALYSIS, 75)) - { - gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE; - // This is removed in FRLG and Emerald for some reason - //CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_IN_LOVE: // infatuation - if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) - { - gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10); - if (!RandomPercentage(RNG_INFATUATION, 50)) - { - BattleScriptPushCursor(); - } - else - { - BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack); - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gProtectStructs[gBattlerAttacker].loveImmobility = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - } - gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_BIDE: // bide - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) - { - gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1); - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) - { - gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; - } - else - { - // This is removed in FRLG and Emerald for some reason - //gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS; - if (gBideDmg[gBattlerAttacker]) - { - gCurrentMove = MOVE_BIDE; - gBattlerTarget = gBideTarget[gBattlerAttacker]; - if (gAbsentBattlerFlags & (1u << gBattlerTarget)) - gBattlerTarget = GetMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1); - gBattlescriptCurrInstr = BattleScript_BideAttack; - } - else - { - gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; - } - } - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_THAW: // move thawing - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE) - { - if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE))) - { - gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE; - } - effect = 2; - } - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && gMovesInfo[gCurrentMove].thawsUser) - { - if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE))) - { - gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedUnfrostbite; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE; - } - effect = 2; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_POWDER_MOVE: - if ((gMovesInfo[gCurrentMove].powderMove) && (gBattlerAttacker != gBattlerTarget)) - { - if (B_POWDER_GRASS >= GEN_6 - && (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT)) - { - gBattlerAbility = gBattlerTarget; - effect = 1; - } - else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES) - { - RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES); - gLastUsedItem = gBattleMons[gBattlerTarget].item; - effect = 1; - } + } + } +} - if (effect != 0) - gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_POWDER_STATUS: - if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER) - { - u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]]; - if ((moveType == TYPE_FIRE && !gBattleStruct->pledgeMove) - || (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE) - || (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove)) - { - gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE; - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD - && (B_POWDER_RAIN < GEN_7 || !IsBattlerWeatherAffected(gBattlerAttacker, B_WEATHER_RAIN_PRIMAL))) - gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; - - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE - || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE)) - gBattlescriptCurrInstr = BattleScript_MoveUsedPowder; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_THROAT_CHOP: - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && gMovesInfo[gCurrentMove].soundMove) - { - gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_Z_MOVES: - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) - { - // For Z-Mirror Move, so it doesn't play the animation twice. - bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE); - - // attacker has a queued z move - RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_Z_CRYSTAL); - SetGimmickAsActivated(gBattlerAttacker, GIMMICK_Z_MOVE); - - gBattleScripting.battler = gBattlerAttacker; - if (gProtectStructs[gBattlerAttacker].powderSelfDmg) - { - if (!alreadyUsed) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ZMoveActivatePowder; - } - } - else if (gMovesInfo[gCurrentMove].category == DAMAGE_CATEGORY_STATUS) - { - if (!alreadyUsed) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus; - } - } - else - { - if (!alreadyUsed) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging; - } - } - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_EXPLODING_DAMP: +static void CancellerFrozen(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !MoveThawsUser(gCurrentMove)) + { + if (!RandomPercentage(RNG_FROZEN, 20)) { - u32 dampBattler = IsAbilityOnField(ABILITY_DAMP); - if (dampBattler && (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION - || gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN)) - { - gBattleScripting.battler = dampBattler - 1; - gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; + gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; + gHitMarker |= (HITMARKER_NO_ATTACKSTRING | HITMARKER_UNABLE_TO_USE_MOVE); + } + else // unfreeze + { + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED; + } + *effect = 2; + } +} + +static void CancellerObedience(u32 *effect) +{ + u32 obedienceResult = GetAttackerObedienceForAction(); + if (obedienceResult != OBEYS + && !(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves + && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + switch (obedienceResult) + { + case DISOBEYS_LOAFS: + // Randomly select, then print a disobedient string + // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE + gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS); + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_HITS_SELF: + gBattlerTarget = gBattlerAttacker; + struct DamageCalculationData damageCalcData; + damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; + damageCalcData.move = MOVE_NONE; + damageCalcData.moveType = TYPE_MYSTERY; + damageCalcData.isCrit = FALSE; + damageCalcData.randomFactor = FALSE; + damageCalcData.updateFlags = TRUE; + gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40); + gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gHitMarker |= HITMARKER_OBEYS; + break; + case DISOBEYS_FALL_ASLEEP: + if (IsSleepClauseEnabled()) + gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; + gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_WHILE_ASLEEP: + gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep; + gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_RANDOM_MOVE: + gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; + SetAtkCancellerForCalledMove(); + gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; + gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gHitMarker |= HITMARKER_DISOBEDIENT_MOVE; + gHitMarker |= HITMARKER_OBEYS; break; } - case CANCELLER_MULTIHIT_MOVES: - if (gMovesInfo[gCurrentMove].effect == EFFECT_MULTI_HIT) + *effect = 1; + } + else + { + gHitMarker |= HITMARKER_OBEYS; + } +} + +static void CancellerTruant(u32 *effect) +{ + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) + { + CancelMultiTurnMoves(gBattlerAttacker); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LOAFING; + gBattlerAbility = gBattlerAttacker; + gBattlescriptCurrInstr = BattleScript_TruantLoafingAround; + gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; + *effect = 1; + } +} + +static void CancellerFlinch(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED) + { + gProtectStructs[gBattlerAttacker].flinchImmobility = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerInLove(u32 *effect) +{ + if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) + { + gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10); + if (!RandomPercentage(RNG_INFATUATION, 50)) + { + BattleScriptPushCursor(); + } + else + { + BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gProtectStructs[gBattlerAttacker].loveImmobility = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + } + gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; + *effect = 1; + } +} + +static void CancellerDisabled(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE) + { + gProtectStructs[gBattlerAttacker].usedDisabledMove = TRUE; + gBattleScripting.battler = gBattlerAttacker; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerHealBlocked(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove)) + { + gProtectStructs[gBattlerAttacker].usedHealBlockedMove = TRUE; + gBattleScripting.battler = gBattlerAttacker; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerGravity(u32 *effect) +{ + if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove)) + { + gProtectStructs[gBattlerAttacker].usedGravityPreventedMove = TRUE; + gBattleScripting.battler = gBattlerAttacker; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerThroatChop(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && IsSoundMove(gCurrentMove)) + { + gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerTaunted(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IsBattleMoveStatus(gCurrentMove)) + { + gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerImprisoned(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove)) + { + gProtectStructs[gBattlerAttacker].usedImprisonedMove = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerConfused(u32 *effect) +{ + if (gBattleStruct->isAtkCancelerForCalledMove) + return; + + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) + { + if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION)) + gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1); + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) + { + // confusion dmg + if (RandomPercentage(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50))) { - u32 ability = GetBattlerAbility(gBattlerAttacker); - - if (ability == ABILITY_SKILL_LINK) - { - gMultiHitCounter = 5; - } - else if (ability == ABILITY_BATTLE_BOND - && gCurrentMove == MOVE_WATER_SHURIKEN - && gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_ASH) - { - gMultiHitCounter = 3; - } - else - { - SetRandomMultiHitCounter(); - } - - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) - } - else if (gMovesInfo[gCurrentMove].strikeCount > 1) - { - if (gMovesInfo[gCurrentMove].effect == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) - { - gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 10); - } - else - { - gMultiHitCounter = gMovesInfo[gCurrentMove].strikeCount; - - if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS - && CanTargetPartner(gBattlerAttacker, gBattlerTarget) - && TargetFullyImmuneToCurrMove(gBattlerAttacker, gBattlerTarget)) - gBattlerTarget = BATTLE_PARTNER(gBattlerTarget); - } - - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0) - } - else if (B_BEAT_UP >= GEN_5 && gMovesInfo[gCurrentMove].effect == EFFECT_BEAT_UP) - { - struct Pokemon* party = GetBattlerParty(gBattlerAttacker); - int i; - - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&party[i], MON_DATA_HP) - && GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[i], MON_DATA_IS_EGG) - && !GetMonData(&party[i], MON_DATA_STATUS)) - gMultiHitCounter++; - } - - gBattleStruct->beatUpSlot = 0; - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) + gBattleCommunication[MULTISTRING_CHOOSER] = TRUE; + gBattlerTarget = gBattlerAttacker; + struct DamageCalculationData damageCalcData; + damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; + damageCalcData.move = MOVE_NONE; + damageCalcData.moveType = TYPE_MYSTERY; + damageCalcData.isCrit = FALSE; + damageCalcData.randomFactor = FALSE; + damageCalcData.updateFlags = TRUE; + gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40); + gProtectStructs[gBattlerAttacker].confusionSelfDmg = TRUE; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; } else { - gMultiHitCounter = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = FALSE; + BattleScriptPushCursor(); } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_MULTI_TARGET_MOVES: - if (!IsDoubleBattle()) + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; + } + else // snapped out of confusion + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; + } + *effect = 1; + } +} + +static void CancellerParalysed(u32 *effect) +{ + if (!gBattleStruct->isAtkCancelerForCalledMove + && (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) + && (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD && B_MAGIC_GUARD >= GEN_4) + && !RandomPercentage(RNG_PARALYSIS, 75)) + { + gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE; + // This is removed in FRLG and Emerald for some reason + //CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerBide(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) + { + gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1); + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) + { + gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; + } + else + { + // This is removed in FRLG and Emerald for some reason + //gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS; + if (gBideDmg[gBattlerAttacker]) { - gBattleStruct->atkCancellerTracker++; - break; + gCurrentMove = MOVE_BIDE; + gBattlerTarget = gBideTarget[gBattlerAttacker]; + if (gAbsentBattlerFlags & (1u << gBattlerTarget)) + gBattlerTarget = GetBattleMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1); + gBattlescriptCurrInstr = BattleScript_BideAttack; } - - u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); - if (IsSpreadMove(moveTarget)) + else { - for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) - { - if (gBattleStruct->bouncedMoveIsUsed && B_SIDE_OPPONENT == GetBattlerSide(battlerDef)) - continue; - - if (gBattlerAttacker == battlerDef - || !IsBattlerAlive(battlerDef) - || (moveTarget == MOVE_TARGET_BOTH && gBattlerAttacker == BATTLE_PARTNER(battlerDef)) - || IsBattlerProtected(gBattlerAttacker, battlerDef, gCurrentMove)) // Missing Invulnerable check - { - gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_NO_EFFECT; - gBattleStruct->noResultString[battlerDef] = TRUE; - } - else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_BLOCK, battlerDef, 0, 0, 0) - || (IsBattlerTerrainAffected(gBattlerAttacker, STATUS_FIELD_PSYCHIC_TERRAIN) && GetMovePriority(gBattlerAttacker, gCurrentMove) > 0)) - { - gBattleStruct->moveResultFlags[battlerDef] = 0; - gBattleStruct->noResultString[battlerDef] = TRUE; - } - else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_ABSORB, battlerDef, 0, 0, gCurrentMove)) - { - gBattleStruct->moveResultFlags[battlerDef] = 0; - gBattleStruct->noResultString[battlerDef] = DO_ACCURACY_CHECK; - } - else - { - CalcTypeEffectivenessMultiplier(gCurrentMove, gMovesInfo[gCurrentMove].type, gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE); - } - } - if (moveTarget == MOVE_TARGET_BOTH) - gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER_SIDE, gBattlerAttacker); - else - gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, gBattlerAttacker); - + gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_END: - break; + } + *effect = 1; + } +} + +static void CancellerThaw(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE) + { + if (!(IsMoveEffectRemoveSpeciesType(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE))) + { + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE; + } + *effect = 2; + } + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && MoveThawsUser(gCurrentMove)) + { + if (!(IsMoveEffectRemoveSpeciesType(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE))) + { + gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfrostbite; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE; + } + *effect = 2; + } +} + +static void CancellerStanceChangeTwo(u32 *effect) +{ + if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove()) + *effect = 1; +} + +static void CancellerWeatherPrimal(u32 *effect) +{ + if (WEATHER_HAS_EFFECT && GetMovePower(gCurrentMove) > 0) + { + u32 moveType = GetBattleMoveType(gCurrentMove); + if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN; + *effect = 1; + } + else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN; + *effect = 1; + } + if (*effect == 1) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; + } + } +} + +static void CancellerDynamaxBlocked(u32 *effect) +{ + if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove)) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax; + *effect = 1; + } +} + +static void CancellerPowderMove(u32 *effect) +{ + if (IsPowderMove(gCurrentMove) && (gBattlerAttacker != gBattlerTarget)) + { + if (B_POWDER_GRASS >= GEN_6 + && (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT)) + { + gBattlerAbility = gBattlerTarget; + *effect = 1; + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES); + gLastUsedItem = gBattleMons[gBattlerTarget].item; + *effect = 1; } - } while (gBattleStruct->atkCancellerTracker != CANCELLER_END && gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0); + if (*effect != 0) + gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect; + } +} + +static void CancellerPowderStatus(u32 *effect) +{ + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER) + { + u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]]; + if ((GetBattleMoveType(gCurrentMove) == TYPE_FIRE && !gBattleStruct->pledgeMove) + || (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE) + || (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove)) + { + gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE; + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD + && (B_POWDER_RAIN < GEN_7 || !IsBattlerWeatherAffected(gBattlerAttacker, B_WEATHER_RAIN_PRIMAL))) + gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; + + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE + || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE)) + gBattlescriptCurrInstr = BattleScript_MoveUsedPowder; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } + } +} + +static void CancellerProtean(u32 *effect) +{ + u32 moveType = GetBattleMoveType(gCurrentMove); + if (ProteanTryChangeType(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), gCurrentMove, moveType)) + { + if (B_PROTEAN_LIBERO == GEN_9) + gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE; + PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); + gBattlerAbility = gBattlerAttacker; + BattleScriptPushCursor(); + PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + gBattlescriptCurrInstr = BattleScript_ProteanActivates; + *effect = 1; + } +} + +static void CancellerPsychicTerrain(u32 *effect) +{ + if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN + && IsBattlerGrounded(gBattlerTarget) + && GetChosenMovePriority(gBattlerAttacker) > 0 + && GetMoveTarget(gCurrentMove) != MOVE_TARGET_ALL_BATTLERS + && GetMoveTarget(gCurrentMove) != MOVE_TARGET_OPPONENTS_FIELD + && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + { + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerExplodingDamp(u32 *effect) +{ + u32 dampBattler = IsAbilityOnField(ABILITY_DAMP); + if (dampBattler && (GetMoveEffect(gCurrentMove) == EFFECT_EXPLOSION + || GetMoveEffect(gCurrentMove) == EFFECT_MIND_BLOWN)) + { + gBattleScripting.battler = dampBattler - 1; + gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + *effect = 1; + } +} + +static void CancellerMultihitMoves(u32 *effect) +{ + if (GetMoveEffect(gCurrentMove) == EFFECT_MULTI_HIT) + { + u32 ability = GetBattlerAbility(gBattlerAttacker); + + if (ability == ABILITY_SKILL_LINK) + { + gMultiHitCounter = 5; + } + else if (ability == ABILITY_BATTLE_BOND + && gCurrentMove == MOVE_WATER_SHURIKEN + && gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_ASH) + { + gMultiHitCounter = 3; + } + else + { + SetRandomMultiHitCounter(); + } + + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) + } + else if (GetMoveStrikeCount(gCurrentMove) > 1) + { + if (GetMoveEffect(gCurrentMove) == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE) + { + gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 10); + } + else + { + gMultiHitCounter = GetMoveStrikeCount(gCurrentMove); + + if (GetMoveEffect(gCurrentMove) == EFFECT_DRAGON_DARTS + && CanTargetPartner(gBattlerAttacker, gBattlerTarget) + && TargetFullyImmuneToCurrMove(gBattlerAttacker, gBattlerTarget)) + gBattlerTarget = BATTLE_PARTNER(gBattlerTarget); + } + + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0) + } + else if (B_BEAT_UP >= GEN_5 && GetMoveEffect(gCurrentMove) == EFFECT_BEAT_UP) + { + struct Pokemon* party = GetBattlerParty(gBattlerAttacker); + int i; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) + && GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && !GetMonData(&party[i], MON_DATA_STATUS)) + gMultiHitCounter++; + } + + gBattleStruct->beatUpSlot = 0; + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) + } + else + { + gMultiHitCounter = 0; + } +} + +static void CancellerZMoves(u32 *effect) +{ + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) + { + // For Z-Mirror Move, so it doesn't play the animation twice. + bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE); + + // attacker has a queued z move + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_Z_CRYSTAL); + SetGimmickAsActivated(gBattlerAttacker, GIMMICK_Z_MOVE); + + gBattleScripting.battler = gBattlerAttacker; + if (gProtectStructs[gBattlerAttacker].powderSelfDmg) + { + if (!alreadyUsed) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ZMoveActivatePowder; + } + } + else if (GetMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_STATUS) + { + if (!alreadyUsed) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus; + } + } + else + { + if (!alreadyUsed) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging; + } + } + *effect = 1; + } +} + +static void CancellerMultiTargetMoves(u32 *effect) +{ + u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); + if (IsSpreadMove(moveTarget)) + { + for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++) + { + if (gBattleStruct->bouncedMoveIsUsed && B_SIDE_OPPONENT == GetBattlerSide(battlerDef)) + continue; + + if (gBattlerAttacker == battlerDef + || !IsBattlerAlive(battlerDef) + || (moveTarget == MOVE_TARGET_BOTH && gBattlerAttacker == BATTLE_PARTNER(battlerDef)) + || IsBattlerProtected(gBattlerAttacker, battlerDef, gCurrentMove)) // Missing Invulnerable check + { + gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_NO_EFFECT; + gBattleStruct->noResultString[battlerDef] = TRUE; + } + else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_BLOCK, battlerDef, 0, 0, 0) + || (IsBattlerTerrainAffected(gBattlerAttacker, STATUS_FIELD_PSYCHIC_TERRAIN) && GetBattleMovePriority(gBattlerAttacker, gCurrentMove) > 0)) + { + gBattleStruct->moveResultFlags[battlerDef] = 0; + gBattleStruct->noResultString[battlerDef] = TRUE; + } + else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_ABSORB, battlerDef, 0, 0, gCurrentMove)) + { + gBattleStruct->moveResultFlags[battlerDef] = 0; + gBattleStruct->noResultString[battlerDef] = DO_ACCURACY_CHECK; + } + else + { + CalcTypeEffectivenessMultiplier(gCurrentMove, GetMoveType(gCurrentMove), gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE); + } + } + if (moveTarget == MOVE_TARGET_BOTH) + gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER_SIDE, gBattlerAttacker); + else + gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, gBattlerAttacker); + } +} + +static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] = +{ + [CANCELLER_FLAGS] = CancellerFlags, + [CANCELLER_STANCE_CHANGE_1] = CancellerStanceChangeOne, + [CANCELLER_SKY_DROP] = CancellerSkyDrop, + [CANCELLER_RECHARGE] = CancellerRecharge, + [CANCELLER_ASLEEP] = CancellerAsleep, + [CANCELLER_FROZEN] = CancellerFrozen, + [CANCELLER_OBEDIENCE] = CancellerObedience, + [CANCELLER_TRUANT] = CancellerTruant, + [CANCELLER_FLINCH] = CancellerFlinch, + [CANCELLER_IN_LOVE] = CancellerInLove, + [CANCELLER_DISABLED] = CancellerDisabled, + [CANCELLER_HEAL_BLOCKED] = CancellerHealBlocked, + [CANCELLER_GRAVITY] = CancellerGravity, + [CANCELLER_THROAT_CHOP] = CancellerThroatChop, + [CANCELLER_TAUNTED] = CancellerTaunted, + [CANCELLER_IMPRISONED] = CancellerImprisoned, + [CANCELLER_CONFUSED] = CancellerConfused, + [CANCELLER_PARALYSED] = CancellerParalysed, + [CANCELLER_BIDE] = CancellerBide, + [CANCELLER_THAW] = CancellerThaw, + [CANCELLER_STANCE_CHANGE_2] = CancellerStanceChangeTwo, + [CANCELLER_WEATHER_PRIMAL] = CancellerWeatherPrimal, + [CANCELLER_DYNAMAX_BLOCKED] = CancellerDynamaxBlocked, + [CANCELLER_POWDER_MOVE] = CancellerPowderMove, + [CANCELLER_POWDER_STATUS] = CancellerPowderStatus, + [CANCELLER_PROTEAN] = CancellerProtean, + [CANCELLER_PSYCHIC_TERRAIN] = CancellerPsychicTerrain, + [CANCELLER_EXPLODING_DAMP] = CancellerExplodingDamp, + [CANCELLER_MULTIHIT_MOVES] = CancellerMultihitMoves, + [CANCELLER_Z_MOVES] = CancellerZMoves, + [CANCELLER_MULTI_TARGET_MOVES] = CancellerMultiTargetMoves, +}; + +u32 AtkCanceller_MoveSuccessOrder(void) +{ + u32 effect = 0; + + while (gBattleStruct->atkCancellerTracker < CANCELLER_END && effect == 0) + { + sMoveSuccessOrderCancellers[gBattleStruct->atkCancellerTracker](&effect); + gBattleStruct->atkCancellerTracker++; + } if (effect == 2) { BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerAttacker].status1); MarkBattlerForControllerExec(gBattlerAttacker); } - return effect; -} - -// After Protean Activation. -u8 AtkCanceller_UnableToUseMove2(void) -{ - u8 effect = 0; - - do - { - switch (gBattleStruct->atkCancellerTracker) - { - case CANCELLER_END: - gBattleStruct->atkCancellerTracker++; - case CANCELLER_PSYCHIC_TERRAIN: - if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN - && IsBattlerGrounded(gBattlerTarget) - && GetChosenMovePriority(gBattlerAttacker) > 0 - && gMovesInfo[gCurrentMove].target != MOVE_TARGET_ALL_BATTLERS - && gMovesInfo[gCurrentMove].target != MOVE_TARGET_OPPONENTS_FIELD - && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - { - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_END2: - break; - } - - } while (gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0); return effect; } @@ -3939,7 +4054,7 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) { if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle))) { - gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; gFieldStatuses |= statusFlag; gDisableStructs[battler].terrainAbilityDone = FALSE; @@ -3976,7 +4091,7 @@ static void ForewarnChooseMove(u32 battler) continue; data[count].moveId = gBattleMons[i].moves[j]; data[count].battler = i; - switch (gMovesInfo[data[count].moveId].effect) + switch (GetMoveEffect(data[count].moveId)) { case EFFECT_OHKO: data[count].power = 150; @@ -3987,12 +4102,15 @@ static void ForewarnChooseMove(u32 battler) data[count].power = 120; break; default: - if (gMovesInfo[data[count].moveId].power == 1) + { + u32 movePower = GetMovePower(data[count].moveId); + if (movePower == 1) data[count].power = 80; else - data[count].power = gMovesInfo[data[count].moveId].power; + data[count].power = movePower; break; } + } count++; } } @@ -4112,11 +4230,11 @@ u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef switch (abilityDef) { case ABILITY_SOUNDPROOF: - if (gMovesInfo[move].soundMove && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER)) + if (IsSoundMove(move) && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER)) effect = MOVE_BLOCKED_BY_SOUNDPROOF_OR_BULLETPROOF; break; case ABILITY_BULLETPROOF: - if (gMovesInfo[move].ballisticMove) + if (IsBallisticMove(move)) effect = MOVE_BLOCKED_BY_SOUNDPROOF_OR_BULLETPROOF; break; case ABILITY_DAZZLING: @@ -4124,13 +4242,13 @@ u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef case ABILITY_ARMOR_TAIL: if (GetBattlerSide(battlerAtk) != GetBattlerSide(battlerDef)) { - u32 priority = AI_DATA->aiCalcInProgress ? GetMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); + u32 priority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); if (priority > 0) effect = MOVE_BLOCKED_BY_DAZZLING; } break; case ABILITY_GOOD_AS_GOLD: - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) { u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); if (!(moveTarget & MOVE_TARGET_OPPONENTS_FIELD) && !(moveTarget & MOVE_TARGET_ALL_BATTLERS)) @@ -4154,7 +4272,7 @@ u32 CanPartnerAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abi case ABILITY_ARMOR_TAIL: if (GetBattlerSide(battlerAtk) != GetBattlerSide(battlerDef)) { - s32 priority = AI_DATA->aiCalcInProgress ? GetMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); + s32 priority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk); if (priority > 0) return MOVE_BLOCKED_BY_PARTNER_DAZZLING; } @@ -4173,7 +4291,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov effect = MOVE_ABSORBED_BY_NO_ABILITY; break; case ABILITY_VOLT_ABSORB: - if (moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS) + if (moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS) effect = MOVE_ABSORBED_BY_DRAIN_HP_ABILITY; break; case ABILITY_WATER_ABSORB: @@ -4186,11 +4304,11 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov effect = MOVE_ABSORBED_BY_DRAIN_HP_ABILITY; break; case ABILITY_MOTOR_DRIVE: - if (moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction) + if (moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction) effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; break; case ABILITY_LIGHTNING_ROD: - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction) + if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction) effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; break; case ABILITY_STORM_DRAIN: @@ -4206,7 +4324,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; break; case ABILITY_WIND_RIDER: - if (gMovesInfo[move].windMove && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER)) + if (IsWindMove(move) && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER)) effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; break; case ABILITY_FLASH_FIRE: @@ -4218,6 +4336,43 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov return effect; } +static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *timer) +{ + if (!(gFieldStatuses & flag)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = message; + gFieldStatuses |= flag; + gBattleScripting.animArg1 = anim; + if (gBattleStruct->startingStatusTimer) + *timer = gBattleStruct->startingStatusTimer; + else + *timer = 0; // Infinite + + return 1; + } + + return 0; +} + +static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u8 *timer) +{ + if (!(gSideStatuses[side] & flag)) + { + gBattlerAttacker = gBattlerTarget = side; + gBattleCommunication[MULTISTRING_CHOOSER] = message; + gSideStatuses[side] |= flag; + gBattleScripting.animArg1 = anim; + if (gBattleStruct->startingStatusTimer) + *timer = gBattleStruct->startingStatusTimer; + else + *timer = 0; // Infinite + + return 1; + } + + return 0; +} + u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg) { u32 effect = 0; @@ -4243,131 +4398,116 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 else move = gCurrentMove; - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); switch (caseID) { case ABILITYEFFECT_SWITCH_IN_STATUSES: // starting field/side/etc statuses with a variable { - u8 timerVal = gBattleStruct->startingStatusTimer; - gBattleScripting.battler = battler; switch (gBattleStruct->startingStatus) { case STARTING_STATUS_ELECTRIC_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; - gFieldStatuses |= STATUS_FIELD_ELECTRIC_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_ELECTRIC_TERRAIN, + B_MSG_TERRAIN_SET_ELECTRIC, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_MISTY_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; - gFieldStatuses |= STATUS_FIELD_MISTY_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_MISTY_TERRAIN, + B_MSG_TERRAIN_SET_MISTY, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_GRASSY_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY; - gFieldStatuses |= STATUS_FIELD_GRASSY_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_GRASSY_TERRAIN, + B_MSG_TERRAIN_SET_GRASSY, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_PSYCHIC_TERRAIN: - if (!(gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; - gFieldStatuses |= STATUS_FIELD_PSYCHIC_TERRAIN; - if (timerVal == 0) - gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT; - else - gFieldTimers.terrainTimer = timerVal; - effect = 2; - } + effect = SetStartingFieldStatus(STATUS_FIELD_PSYCHIC_TERRAIN, + B_MSG_TERRAIN_SET_PSYCHIC, + 0, + &gFieldTimers.terrainTimer); + effect = (effect == 1) ? 2 : 0; break; case STARTING_STATUS_TRICK_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_TRICK_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TRICK_ROOM; - gFieldStatuses |= STATUS_FIELD_TRICK_ROOM; - gBattleScripting.animArg1 = B_ANIM_TRICK_ROOM; - if (timerVal == 0) - gFieldTimers.trickRoomTimer = 0; // infinite - else - gFieldTimers.trickRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_TRICK_ROOM, + B_MSG_SET_TRICK_ROOM, + B_ANIM_TRICK_ROOM, + &gFieldTimers.trickRoomTimer); break; case STARTING_STATUS_MAGIC_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MAGIC_ROOM; - gFieldStatuses |= STATUS_FIELD_MAGIC_ROOM; - gBattleScripting.animArg1 = B_ANIM_MAGIC_ROOM; - if (timerVal == 0) - gFieldTimers.magicRoomTimer = 0; // infinite - else - gFieldTimers.magicRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_MAGIC_ROOM, + B_MSG_SET_MAGIC_ROOM, + B_ANIM_MAGIC_ROOM, + &gFieldTimers.magicRoomTimer); break; case STARTING_STATUS_WONDER_ROOM: - if (!(gFieldStatuses & STATUS_FIELD_WONDER_ROOM)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_WONDER_ROOM; - gFieldStatuses |= STATUS_FIELD_WONDER_ROOM; - gBattleScripting.animArg1 = B_ANIM_WONDER_ROOM; - if (timerVal == 0) - gFieldTimers.wonderRoomTimer = 0; // infinite - else - gFieldTimers.wonderRoomTimer = 5; - effect = 1; - } + effect = SetStartingFieldStatus(STATUS_FIELD_WONDER_ROOM, + B_MSG_SET_WONDER_ROOM, + B_ANIM_WONDER_ROOM, + &gFieldTimers.wonderRoomTimer); break; case STARTING_STATUS_TAILWIND_PLAYER: - if (!(gSideStatuses[B_SIDE_PLAYER] & SIDE_STATUS_TAILWIND)) - { - gBattlerAttacker = B_POSITION_PLAYER_LEFT; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_PLAYER; - gSideStatuses[B_SIDE_PLAYER] |= SIDE_STATUS_TAILWIND; - gBattleScripting.animArg1 = B_ANIM_TAILWIND; - if (timerVal == 0) - gSideTimers[B_SIDE_PLAYER].tailwindTimer = 0; // infinite - else - gSideTimers[B_SIDE_PLAYER].tailwindTimer = 5; - effect = 1; - } + effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND, + B_SIDE_PLAYER, + B_MSG_SET_TAILWIND, + B_ANIM_TAILWIND, + &gSideTimers[B_SIDE_PLAYER].tailwindTimer); break; case STARTING_STATUS_TAILWIND_OPPONENT: - if (!(gSideStatuses[B_SIDE_OPPONENT] & SIDE_STATUS_TAILWIND)) - { - gBattlerAttacker = B_POSITION_OPPONENT_LEFT; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_OPPONENT; - gSideStatuses[B_SIDE_OPPONENT] |= SIDE_STATUS_TAILWIND; - gBattleScripting.animArg1 = B_ANIM_TAILWIND; - if (timerVal == 0) - gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 0; // infinite - else - gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 5; - effect = 1; - } + effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND, + B_SIDE_OPPONENT, + B_MSG_SET_TAILWIND, + B_ANIM_TAILWIND, + &gSideTimers[B_SIDE_OPPONENT].tailwindTimer); + break; + case STARTING_STATUS_RAINBOW_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW, + B_SIDE_PLAYER, + B_MSG_SET_RAINBOW, + B_ANIM_RAINBOW, + &gSideTimers[B_SIDE_PLAYER].rainbowTimer); + break; + case STARTING_STATUS_RAINBOW_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW, + B_SIDE_OPPONENT, + B_MSG_SET_RAINBOW, + B_ANIM_RAINBOW, + &gSideTimers[B_SIDE_OPPONENT].rainbowTimer); + break; + case STARTING_STATUS_SEA_OF_FIRE_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE, + B_SIDE_PLAYER, + B_MSG_SET_SEA_OF_FIRE, + B_ANIM_SEA_OF_FIRE, + &gSideTimers[B_SIDE_PLAYER].seaOfFireTimer); + break; + case STARTING_STATUS_SEA_OF_FIRE_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE, + B_SIDE_OPPONENT, + B_MSG_SET_SEA_OF_FIRE, + B_ANIM_SEA_OF_FIRE, + &gSideTimers[B_SIDE_OPPONENT].seaOfFireTimer); + break; + case STARTING_STATUS_SWAMP_PLAYER: + effect = SetStartingSideStatus(SIDE_STATUS_SWAMP, + B_SIDE_PLAYER, + B_MSG_SET_SWAMP, + B_ANIM_SWAMP, + &gSideTimers[B_SIDE_PLAYER].swampTimer); + break; + case STARTING_STATUS_SWAMP_OPPONENT: + effect = SetStartingSideStatus(SIDE_STATUS_SWAMP, + B_SIDE_OPPONENT, + B_MSG_SET_SWAMP, + B_ANIM_SWAMP, + &gSideTimers[B_SIDE_OPPONENT].swampTimer); break; } @@ -4383,7 +4523,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM) { // overworld weather started rain, so just do electric terrain anim - gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses = STATUS_FIELD_ELECTRIC_TERRAIN; + gFieldTimers.terrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; @@ -4392,7 +4533,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL) && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) { - gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); + gFieldStatuses = STATUS_FIELD_MISTY_TERRAIN; + gFieldTimers.terrainTimer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; @@ -4612,7 +4754,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 for (j = 0; j < MAX_MON_MOVES; j++) { move = gBattleMons[i].moves[j]; - moveType = GetMoveType(move); + moveType = GetBattleMoveType(move); if (CalcTypeEffectivenessMultiplier(move, moveType, i, battler, ABILITY_ANTICIPATION, FALSE) >= UQ_4_12(2.0)) { effect++; @@ -5353,7 +5495,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 default: if (GetChosenMovePriority(gBattlerAttacker) > 0 && BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE) - && !(IS_MOVE_STATUS(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove))) + && !(IsBattleMoveStatus(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove))) { if (!IsDoubleBattle() || !(GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) @@ -5568,11 +5710,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (MoveResultHasEffect(battler) && IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(battler) - && IS_MOVE_PHYSICAL(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_DEF, MIN_STAT_STAGE, CMP_GREATER_THAN))) { - if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker)) + if (GetMoveEffect(gCurrentMove) == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker)) gProtectStructs[battler].disableEjectPack = TRUE; // Set flag for target BattleScriptPushCursor(); @@ -5664,7 +5806,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_COLOR_CHANGE: if (MoveResultHasEffect(battler) && move != MOVE_STRUGGLE - && !IS_MOVE_STATUS(move) + && !IsBattleMoveStatus(move) && IsBattlerTurnDamaged(gBattlerTarget) && !IS_BATTLER_OF_TYPE(battler, moveType) && moveType != TYPE_STELLAR @@ -6025,7 +6167,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_WIND_POWER: - if (!(gMovesInfo[gCurrentMove].windMove)) + if (!IsWindMove(gCurrentMove)) break; // fall through case ABILITY_ELECTROMORPHOSIS: @@ -6043,7 +6185,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (MoveResultHasEffect(gBattlerTarget) && (!gBattleStruct->isSkyBattle) && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && IS_MOVE_PHYSICAL(gCurrentMove) + && IsBattleMovePhysical(gCurrentMove) && IsBattlerTurnDamaged(gBattlerTarget) && (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2)) { @@ -6137,7 +6279,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { case ABILITY_DANCER: if (IsBattlerAlive(battler) - && (gMovesInfo[gCurrentMove].danceMove) + && IsDanceMove(gCurrentMove) && !gSpecialStatuses[battler].dancerUsedMove && gBattlerAttacker != battler) { @@ -6483,12 +6625,12 @@ bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability) return FALSE; return (ability == ABILITY_MOLD_BREAKER || ability == ABILITY_TERAVOLT || ability == ABILITY_TURBOBLAZE - || (ability == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove))); + || (ability == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gCurrentMove))); } static inline bool32 CanBreakThroughAbility(u32 battlerAtk, u32 battlerDef, u32 ability) { - return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || gMovesInfo[gCurrentMove].ignoresTargetAbility) + return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || MoveIgnoresTargetAbility(gCurrentMove)) && battlerDef != battlerAtk && gAbilitiesInfo[gBattleMons[battlerDef].ability].breakable && gBattlerByTurnOrder[gCurrentTurnActionNumber] == battlerAtk @@ -7993,7 +8135,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) if (gBattleStruct->moveDamage[battler] != 0 // Need to have done damage && MoveResultHasEffect(gBattlerTarget) && IsBattlerTurnDamaged(gBattlerTarget) - && !gMovesInfo[gCurrentMove].ignoresKingsRock + && !MoveIgnoresKingsRock(gCurrentMove) && gBattleMons[gBattlerTarget].hp && RandomPercentage(RNG_HOLD_EFFECT_FLINCH, atkHoldEffectParam) && ability != ABILITY_STENCH) @@ -8063,7 +8205,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) case HOLD_EFFECT_THROAT_SPRAY: // Does NOT need to be a damaging move if (gProtectStructs[gBattlerAttacker].targetAffected && IsBattlerAlive(gBattlerAttacker) - && gMovesInfo[gCurrentMove].soundMove + && IsSoundMove(gCurrentMove) && CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN) && !NoAliveMonsForEitherParty()) // Don't activate if battle will end { @@ -8080,7 +8222,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) case ITEMEFFECT_TARGET: if (MoveResultHasEffect(gBattlerTarget)) { - moveType = GetMoveType(gCurrentMove); + moveType = GetBattleMoveType(gCurrentMove); switch (battlerHoldEffect) { case HOLD_EFFECT_AIR_BALLOON: @@ -8169,7 +8311,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) if (IsBattlerAlive(battler) && IsBattlerTurnDamaged(gBattlerTarget) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) - && IS_MOVE_PHYSICAL(gCurrentMove) + && IsBattleMovePhysical(gCurrentMove) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) { gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8; @@ -8189,7 +8331,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) if (IsBattlerAlive(battler) && IsBattlerTurnDamaged(gBattlerTarget) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) - && IS_MOVE_SPECIAL(gCurrentMove) + && IsBattleMoveSpecial(gCurrentMove) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) { gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8; @@ -8213,7 +8355,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) break; case HOLD_EFFECT_CURE_STATUS: // only Toxic Chain's interaction with Knock Off case HOLD_EFFECT_CURE_PSN: - if (gBattleMons[battler].status1 & STATUS1_PSN_ANY && !UnnerveOn(battler, gLastUsedItem) && GetBattlerAbility(gBattlerAttacker) == ABILITY_TOXIC_CHAIN && gMovesInfo[gCurrentMove].effect == EFFECT_KNOCK_OFF) + if (gBattleMons[battler].status1 & STATUS1_PSN_ANY && !UnnerveOn(battler, gLastUsedItem) && GetBattlerAbility(gBattlerAttacker) == ABILITY_TOXIC_CHAIN && GetMoveEffect(gCurrentMove) == EFFECT_KNOCK_OFF) { gBattleScripting.battler = battler; gBattleMons[battler].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER); @@ -8299,6 +8441,18 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn) gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; } break; + case HOLD_EFFECT_EJECT_PACK: + if (gProtectStructs[battler].statFell + && gProtectStructs[battler].disableEjectPack == 0 + && CountUsablePartyMons(battler) > 0) + { + gBattleScripting.battler = battler; + gPotentialItemEffectBattler = battler; + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_EjectPackActivates; + } + break; } break; } @@ -8347,11 +8501,11 @@ u32 SetRandomTarget(u32 battlerAtk) return target; } -u32 GetMoveTarget(u16 move, u8 setTarget) +u32 GetBattleMoveTarget(u16 move, u8 setTarget) { u8 targetBattler = 0; u32 moveTarget, side; - u32 moveType = GetMoveType(move); + u32 moveType = GetBattleMoveType(move); if (setTarget != NO_TARGET_OVERRIDE) moveTarget = setTarget - 1; @@ -8488,7 +8642,8 @@ u8 GetAttackerObedienceForAction() // is not obedient if (gCurrentMove == MOVE_RAGE) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE; - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gMovesInfo[gCurrentMove].effect == EFFECT_SNORE || gMovesInfo[gCurrentMove].effect == EFFECT_SLEEP_TALK)) + u32 moveEffect = GetMoveEffect(gCurrentMove); + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (moveEffect == EFFECT_SNORE || moveEffect == EFFECT_SLEEP_TALK)) return DISOBEYS_WHILE_ASLEEP; calc = (levelReferenced + obedienceLevel) * ((rnd >> 8) & 255) >> 8; @@ -8576,14 +8731,14 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk) { u32 atkHoldEffect = GetBattlerHoldEffect(battlerAtk, TRUE); - if (!gMovesInfo[move].makesContact) + if (!MoveMakesContact(move)) { - if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL) + if (GetMoveEffect(move) == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL) return TRUE; else return FALSE; } - else if ((atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE && gMovesInfo[move].punchingMove) + else if ((atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE && IsPunchingMove(move)) || GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH) { return FALSE; @@ -8599,7 +8754,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) bool32 isProtected = FALSE; if ((IsZMove(move) || IsMaxMove(move)) - && (!gProtectStructs[battlerDef].maxGuarded || gMovesInfo[move].argument == MAX_EFFECT_BYPASS_PROTECT)) + && (!gProtectStructs[battlerDef].maxGuarded || GetMoveMaxEffect(move) == MAX_EFFECT_BYPASS_PROTECT)) isProtected = FALSE; // Z-Moves and Max Moves bypass protection (except Max Guard). else if (gProtectStructs[battlerDef].maxGuarded && IsMoveBlockedByMaxGuard(move)) isProtected = TRUE; @@ -8607,9 +8762,9 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) && IsMoveMakingContact(move, gBattlerAttacker) && GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST) isProtected = FALSE; - else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_COACHING) + else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD && IsBattleMoveStatus(move) && GetMoveEffect(move) != EFFECT_COACHING) isProtected = TRUE; - else if (gMovesInfo[move].ignoresProtect) + else if (MoveIgnoresProtect(move)) isProtected = FALSE; else if (gProtectStructs[battlerDef].protected) isProtected = TRUE; @@ -8620,11 +8775,11 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) isProtected = TRUE; else if (gProtectStructs[battlerDef].burningBulwarked) isProtected = TRUE; - else if ((gProtectStructs[battlerDef].obstructed || gProtectStructs[battlerDef].silkTrapped) && !IS_MOVE_STATUS(move)) + else if ((gProtectStructs[battlerDef].obstructed || gProtectStructs[battlerDef].silkTrapped) && !IsBattleMoveStatus(move)) isProtected = TRUE; else if (gProtectStructs[battlerDef].spikyShielded) isProtected = TRUE; - else if (gProtectStructs[battlerDef].kingsShielded && !IS_MOVE_STATUS(move)) + else if (gProtectStructs[battlerDef].kingsShielded && !IsBattleMoveStatus(move)) isProtected = TRUE; else if (gProtectStructs[battlerDef].maxGuarded) isProtected = TRUE; @@ -8632,7 +8787,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) && GetChosenMovePriority(gBattlerAttacker) > 0) isProtected = TRUE; else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_MAT_BLOCK - && !IS_MOVE_STATUS(move)) + && !IsBattleMoveStatus(move)) isProtected = TRUE; else isProtected = FALSE; @@ -8898,7 +9053,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData u32 move = damageCalcData->move; u32 i; - u32 basePower = gMovesInfo[move].power; + u32 basePower = GetMovePower(move); u32 weight, hpFraction, speed; if (GetActiveGimmick(battlerAtk) == GIMMICK_Z_MOVE) @@ -8907,7 +9062,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX) return GetMaxMovePower(move); - switch (gMovesInfo[move].effect) + switch (GetMoveEffect(move)) { case EFFECT_PLEDGE: if (gBattleStruct->pledgeMove) @@ -8947,7 +9102,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData basePower = gBattleStruct->presentBasePower; break; case EFFECT_TRIPLE_KICK: - basePower *= 1 + gMovesInfo[move].strikeCount - gMultiHitCounter; + basePower *= 1 + GetMoveStrikeCount(move) - gMultiHitCounter; break; case EFFECT_SPIT_UP: basePower = 100 * gDisableStructs[battlerAtk].stockpileCounter; @@ -8972,8 +9127,8 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData break; case EFFECT_DOUBLE_POWER_ON_ARG_STATUS: // Comatose targets treated as if asleep - if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & gMovesInfo[move].argument - && !((gMovesInfo[move].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS) && DoesSubstituteBlockMove(battlerAtk, battlerDef, move))) + if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & GetMoveEffectArg_Status(move) + && !((GetMoveAdditionalEffectById(move, 0)->moveEffect == MOVE_EFFECT_REMOVE_STATUS) && DoesSubstituteBlockMove(battlerAtk, battlerDef, move))) { basePower *= 2; } @@ -9061,7 +9216,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData case EFFECT_ROUND: for (i = 0; i < gBattlersCount; i++) { - if (i != battlerAtk && IsBattlerAlive(i) && gLastMoves[i] == MOVE_ROUND) + if (i != battlerAtk && IsBattlerAlive(i) && GetMoveEffect(gLastUsedMove) == EFFECT_ROUND) { basePower *= 2; break; @@ -9069,7 +9224,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData } break; case EFFECT_FUSION_COMBO: - if (gMovesInfo[gLastUsedMove].effect == EFFECT_FUSION_COMBO && move != gLastUsedMove) + if (GetMoveEffect(gLastUsedMove) == EFFECT_FUSION_COMBO && move != gLastUsedMove) basePower *= 2; break; case EFFECT_LASH_OUT: @@ -9167,13 +9322,14 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * u32 battlerDef = damageCalcData->battlerDef; u32 move = damageCalcData->move; u32 moveType = damageCalcData->moveType; + u32 moveEffect = GetMoveEffect(move); uq4_12_t holdEffectModifier; uq4_12_t modifier = UQ_4_12(1.0); u32 atkSide = GetBattlerSide(battlerAtk); // move effect - switch (gMovesInfo[move].effect) + switch (moveEffect) { case EFFECT_FACADE: if (gBattleMons[battlerAtk].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_PARALYSIS | STATUS1_FROSTBITE)) @@ -9241,19 +9397,19 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_FLARE_BOOST: - if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && IS_MOVE_SPECIAL(move)) + if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_TOXIC_BOOST: - if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY && IS_MOVE_PHYSICAL(move)) + if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY && IsBattleMovePhysical(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_RECKLESS: - if (IS_MOVE_RECOIL(move)) + if (IsBattleMoveRecoil(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.2)); break; case ABILITY_IRON_FIST: - if (gMovesInfo[move].punchingMove) + if (IsPunchingMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.2)); break; case ABILITY_SHEER_FORCE: @@ -9280,11 +9436,11 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); break; case ABILITY_STRONG_JAW: - if (gMovesInfo[move].bitingMove) + if (IsBitingMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_MEGA_LAUNCHER: - if (gMovesInfo[move].pulseMove) + if (IsPulseMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_WATER_BUBBLE: @@ -9316,7 +9472,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, UQ_4_12(1.2)); break; case ABILITY_PUNK_ROCK: - if (gMovesInfo[move].soundMove) + if (IsSoundMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); break; case ABILITY_STEELY_SPIRIT: @@ -9324,7 +9480,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_SHARPNESS: - if (gMovesInfo[move].slicingMove) + if (IsSlicingMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_SUPREME_OVERLORD: @@ -9348,7 +9504,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk))) { case ABILITY_BATTERY: - if (IS_MOVE_SPECIAL(move)) + if (IsBattleMoveSpecial(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); break; case ABILITY_POWER_SPOT: @@ -9381,7 +9537,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * { u8 defHighestStat = GetHighestStatId(battlerDef); if (((weather & B_WEATHER_SUN && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerDef)) - && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF)) + && ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF)) && !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED)) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -9390,7 +9546,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * { u8 defHighestStat = GetHighestStatId(battlerDef); if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerDef)) - && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF)) + && ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF)) && !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED)) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -9407,11 +9563,11 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * switch (holdEffectAtk) { case HOLD_EFFECT_MUSCLE_BAND: - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12_Floored(holdEffectParamAtk))); break; case HOLD_EFFECT_WISE_GLASSES: - if (IS_MOVE_SPECIAL(move)) + if (IsBattleMoveSpecial(move)) modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12_Floored(holdEffectParamAtk))); break; case HOLD_EFFECT_LUSTROUS_ORB: @@ -9429,7 +9585,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * case HOLD_EFFECT_SOUL_DEW: if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS) && ((B_SOUL_DEW_BOOST >= GEN_7 && (moveType == TYPE_PSYCHIC || moveType == TYPE_DRAGON)) - || (B_SOUL_DEW_BOOST < GEN_7 && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IS_MOVE_SPECIAL(move)))) + || (B_SOUL_DEW_BOOST < GEN_7 && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IsBattleMoveSpecial(move)))) modifier = uq4_12_multiply(modifier, holdEffectModifier); break; case HOLD_EFFECT_BUG_POWER: @@ -9465,7 +9621,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, holdEffectModifier); break; case HOLD_EFFECT_PUNCHING_GLOVE: - if (gMovesInfo[move].punchingMove) + if (IsPunchingMove(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.1)); break; case HOLD_EFFECT_OGERPON_MASK: @@ -9479,9 +9635,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * && (moveType == GetBattlerTeraType(battlerAtk) || (GetBattlerTeraType(battlerAtk) == TYPE_STELLAR && IsTypeStellarBoosted(battlerAtk, moveType))) && uq4_12_multiply_by_int_half_down(modifier, basePower) < 60 - && gMovesInfo[move].strikeCount < 2 - && gMovesInfo[move].effect != EFFECT_MULTI_HIT - && gMovesInfo[move].priority == 0) + && GetMoveStrikeCount(move) < 2 + && moveEffect != EFFECT_MULTI_HIT + && GetMovePriority(move) == 0) { return 60; } @@ -9499,12 +9655,13 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u u32 battlerDef = damageCalcData->battlerDef; u32 move = damageCalcData->move; u32 moveType = damageCalcData->moveType; + u32 moveEffect = GetMoveEffect(move); atkBaseSpeciesId = GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species); - if (gMovesInfo[move].effect == EFFECT_FOUL_PLAY) + if (moveEffect == EFFECT_FOUL_PLAY) { - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) { atkStat = gBattleMons[battlerDef].attack; atkStage = gBattleMons[battlerDef].statStages[STAT_ATK]; @@ -9515,9 +9672,9 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u atkStage = gBattleMons[battlerDef].statStages[STAT_SPATK]; } } - else if (gMovesInfo[move].effect == EFFECT_BODY_PRESS) + else if (moveEffect == EFFECT_BODY_PRESS) { - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) { atkStat = gBattleMons[battlerAtk].defense; // Edge case: Body Press used during Wonder Room. For some reason, it still uses Defense over Sp.Def, but uses Sp.Def stat changes @@ -9534,7 +9691,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u } else { - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) { atkStat = gBattleMons[battlerAtk].attack; atkStage = gBattleMons[battlerAtk].statStages[STAT_ATK]; @@ -9564,7 +9721,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u { case ABILITY_HUGE_POWER: case ABILITY_PURE_POWER: - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; case ABILITY_SLOW_START: @@ -9572,7 +9729,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.5)); break; case ABILITY_SOLAR_POWER: - if (IS_MOVE_SPECIAL(move) && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN)) + if (IsBattleMoveSpecial(move) && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_DEFEATIST: @@ -9600,7 +9757,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_PLUS: - if (IS_MOVE_SPECIAL(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) + if (IsBattleMoveSpecial(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) { u32 partnerAbility = GetBattlerAbility(BATTLE_PARTNER(battlerAtk)); if (partnerAbility == ABILITY_MINUS @@ -9609,7 +9766,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u } break; case ABILITY_MINUS: - if (IS_MOVE_SPECIAL(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) + if (IsBattleMoveSpecial(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk))) { u32 partnerAbility = GetBattlerAbility(BATTLE_PARTNER(battlerAtk)); if (partnerAbility == ABILITY_PLUS @@ -9618,11 +9775,11 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u } break; case ABILITY_FLOWER_GIFT: - if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move)) + if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_HUSTLE: - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_STAKEOUT: @@ -9630,7 +9787,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; case ABILITY_GUTS: - if (gBattleMons[battlerAtk].status1 & STATUS1_ANY && IS_MOVE_PHYSICAL(move)) + if (gBattleMons[battlerAtk].status1 & STATUS1_ANY && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_TRANSISTOR: @@ -9647,7 +9804,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_GORILLA_TACTICS: - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.5)); break; case ABILITY_ROCKY_PAYLOAD: @@ -9660,7 +9817,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u u32 atkHighestStat = GetHighestStatId(battlerAtk); if (((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk)) { - if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK)) + if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } } @@ -9671,17 +9828,17 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u u32 atkHighestStat = GetHighestStatId(battlerAtk); if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk)) { - if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK)) + if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } } break; case ABILITY_ORICHALCUM_PULSE: - if ((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && IS_MOVE_PHYSICAL(move)) + if ((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && IsBattleMovePhysical(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333)); break; case ABILITY_HADRON_ENGINE: - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IS_MOVE_SPECIAL(move)) + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333)); break; } @@ -9705,49 +9862,49 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk))) { case ABILITY_FLOWER_GIFT: - if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move)) + if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; } } // field abilities - if (IsAbilityOnField(ABILITY_VESSEL_OF_RUIN) && atkAbility != ABILITY_VESSEL_OF_RUIN && IS_MOVE_SPECIAL(move)) + if (IsAbilityOnField(ABILITY_VESSEL_OF_RUIN) && atkAbility != ABILITY_VESSEL_OF_RUIN && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.75)); - if (IsAbilityOnField(ABILITY_TABLETS_OF_RUIN) && atkAbility != ABILITY_TABLETS_OF_RUIN && IS_MOVE_PHYSICAL(move)) + if (IsAbilityOnField(ABILITY_TABLETS_OF_RUIN) && atkAbility != ABILITY_TABLETS_OF_RUIN && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.75)); // attacker's hold effect switch (holdEffectAtk) { case HOLD_EFFECT_THICK_CLUB: - if ((atkBaseSpeciesId == SPECIES_CUBONE || atkBaseSpeciesId == SPECIES_MAROWAK) && IS_MOVE_PHYSICAL(move)) + if ((atkBaseSpeciesId == SPECIES_CUBONE || atkBaseSpeciesId == SPECIES_MAROWAK) && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; case HOLD_EFFECT_DEEP_SEA_TOOTH: - if (gBattleMons[battlerAtk].species == SPECIES_CLAMPERL && IS_MOVE_SPECIAL(move)) + if (gBattleMons[battlerAtk].species == SPECIES_CLAMPERL && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; case HOLD_EFFECT_LIGHT_BALL: - if (atkBaseSpeciesId == SPECIES_PIKACHU && (B_LIGHT_BALL_ATTACK_BOOST >= GEN_4 || IS_MOVE_SPECIAL(move))) + if (atkBaseSpeciesId == SPECIES_PIKACHU && (B_LIGHT_BALL_ATTACK_BOOST >= GEN_4 || IsBattleMoveSpecial(move))) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; case HOLD_EFFECT_CHOICE_BAND: - if (IS_MOVE_PHYSICAL(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) + if (IsBattleMovePhysical(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case HOLD_EFFECT_CHOICE_SPECS: - if (IS_MOVE_SPECIAL(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) + if (IsBattleMoveSpecial(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; } // The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the 1st badge and 7th badges. // Having the 1st badge boosts physical attack while having the 7th badge boosts special attack. - if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, battlerAtk) && IS_MOVE_PHYSICAL(move)) + if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, battlerAtk) && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1)); - if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerAtk) && IS_MOVE_SPECIAL(move)) + if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerAtk) && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1)); return uq4_12_multiply_by_int_half_down(modifier, atkStat); @@ -9779,6 +9936,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData, u32 battlerDef = damageCalcData->battlerDef; u32 move = damageCalcData->move; u32 moveType = damageCalcData->moveType; + u32 moveEffect = GetMoveEffect(move); if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) // the defense stats are swapped { @@ -9791,7 +9949,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData, spDef = gBattleMons[battlerDef].spDefense; } - if (gMovesInfo[move].effect == EFFECT_PSYSHOCK || IS_MOVE_PHYSICAL(move)) // uses defense stat instead of sp.def + if (moveEffect == EFFECT_PSYSHOCK || IsBattleMovePhysical(move)) // uses defense stat instead of sp.def { defStat = def; defStage = gBattleMons[battlerDef].statStages[STAT_DEF]; @@ -9805,7 +9963,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData, } // Self-destruct / Explosion cut defense in half - if (B_EXPLOSION_DEFENSE < GEN_5 && gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION) + if (B_EXPLOSION_DEFENSE < GEN_5 && moveEffect == EFFECT_EXPLOSION) defStat /= 2; // critical hits ignore positive stat changes @@ -9815,7 +9973,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData, if (atkAbility == ABILITY_UNAWARE) defStage = DEFAULT_STAT_STAGE; // certain moves also ignore stat changes - if (gMovesInfo[move].ignoresTargetDefenseEvasionStages) + if (MoveIgnoresDefenseEvasionStages(move)) defStage = DEFAULT_STAT_STAGE; defStat *= gStatStageRatios[defStage][0]; @@ -9917,9 +10075,9 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData, // The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the 5th badge and 7th badges. // Having the 5th badge boosts physical defense while having the 7th badge boosts special defense. - if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, battlerDef) && IS_MOVE_PHYSICAL(move)) + if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, battlerDef) && IsBattleMovePhysical(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1)); - if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerDef) && IS_MOVE_SPECIAL(move)) + if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerDef) && IsBattleMoveSpecial(move)) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1)); return uq4_12_multiply_by_int_half_down(modifier, defStat); @@ -9968,7 +10126,7 @@ static uq4_12_t GetWeatherDamageModifier(struct DamageCalculationData *damageCal if (weather == B_WEATHER_NONE) return UQ_4_12(1.0); - if (gMovesInfo[move].effect == EFFECT_HYDRO_STEAM && (weather & B_WEATHER_SUN) && holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA) + if (GetMoveEffect(move) == EFFECT_HYDRO_STEAM && (weather & B_WEATHER_SUN) && holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA) return UQ_4_12(1.5); if (holdEffectDef == HOLD_EFFECT_UTILITY_UMBRELLA) return UQ_4_12(1.0); @@ -9992,15 +10150,16 @@ static inline uq4_12_t GetBurnOrFrostBiteModifier(struct DamageCalculationData * { u32 battlerAtk = damageCalcData->battlerAtk; u32 move = damageCalcData->move; + u32 moveEffect = GetMoveEffect(move); if (gBattleMons[battlerAtk].status1 & STATUS1_BURN - && IS_MOVE_PHYSICAL(move) - && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE) + && IsBattleMovePhysical(move) + && (B_BURN_FACADE_DMG < GEN_6 || moveEffect != EFFECT_FACADE) && abilityAtk != ABILITY_GUTS) return UQ_4_12(0.5); if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE - && IS_MOVE_SPECIAL(move) - && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE)) + && IsBattleMoveSpecial(move) + && (B_BURN_FACADE_DMG < GEN_6 || moveEffect != EFFECT_FACADE)) return UQ_4_12(0.5); return UQ_4_12(1.0); } @@ -10028,28 +10187,28 @@ static inline uq4_12_t GetZMaxMoveAgainstProtectionModifier(struct DamageCalcula static inline uq4_12_t GetMinimizeModifier(u32 move, u32 battlerDef) { - if (gMovesInfo[move].minimizeDoubleDamage && gStatuses3[battlerDef] & STATUS3_MINIMIZED) + if (MoveIncreasesPowerToMinimizedTargets(move) && gStatuses3[battlerDef] & STATUS3_MINIMIZED) return UQ_4_12(2.0); return UQ_4_12(1.0); } static inline uq4_12_t GetUndergroundModifier(u32 move, u32 battlerDef) { - if (gMovesInfo[move].damagesUnderground && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) + if (MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) return UQ_4_12(2.0); return UQ_4_12(1.0); } static inline uq4_12_t GetDiveModifier(u32 move, u32 battlerDef) { - if (gMovesInfo[move].damagesUnderwater && gStatuses3[battlerDef] & STATUS3_UNDERWATER) + if (MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER) return UQ_4_12(2.0); return UQ_4_12(1.0); } static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef) { - if (gMovesInfo[move].damagesAirborneDoubleDamage && gStatuses3[battlerDef] & STATUS3_ON_AIR) + if (MoveDamagesAirborneDoubleDamage(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR) return UQ_4_12(2.0); return UQ_4_12(1.0); } @@ -10057,8 +10216,8 @@ static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef) static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerDef, bool32 isCrit, u32 abilityAtk) { u32 sideStatus = gSideStatuses[GetBattlerSide(battlerDef)]; - bool32 lightScreen = (sideStatus & SIDE_STATUS_LIGHTSCREEN) && IS_MOVE_SPECIAL(move); - bool32 reflect = (sideStatus & SIDE_STATUS_REFLECT) && IS_MOVE_PHYSICAL(move); + bool32 lightScreen = (sideStatus & SIDE_STATUS_LIGHTSCREEN) && IsBattleMoveSpecial(move); + bool32 reflect = (sideStatus & SIDE_STATUS_REFLECT) && IsBattleMovePhysical(move); bool32 auroraVeil = sideStatus & SIDE_STATUS_AURORA_VEIL; if (isCrit || abilityAtk == ABILITY_INFILTRATOR || gProtectStructs[battlerAtk].confusionSelfDmg) @@ -10070,7 +10229,7 @@ static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerD static inline uq4_12_t GetCollisionCourseElectroDriftModifier(u32 move, uq4_12_t typeEffectivenessModifier) { - if (gMovesInfo[move].effect == EFFECT_COLLISION_COURSE && typeEffectivenessModifier >= UQ_4_12(2.0)) + if (GetMoveEffect(move) == EFFECT_COLLISION_COURSE && typeEffectivenessModifier >= UQ_4_12(2.0)) return UQ_4_12(1.3333); return UQ_4_12(1.0); } @@ -10117,11 +10276,11 @@ static inline uq4_12_t GetDefenderAbilitiesModifier(u32 move, u32 moveType, u32 return UQ_4_12(0.5); break; case ABILITY_PUNK_ROCK: - if (gMovesInfo[move].soundMove) + if (IsSoundMove(move)) return UQ_4_12(0.5); break; case ABILITY_ICE_SCALES: - if (IS_MOVE_SPECIAL(move)) + if (IsBattleMoveSpecial(move)) return UQ_4_12(0.5); break; } @@ -10320,9 +10479,9 @@ static inline s32 DoFutureSightAttackDamageCalcVars(struct DamageCalculationData struct Pokemon *partyMon = &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]]; u32 partyMonLevel = GetMonData(partyMon, MON_DATA_LEVEL, NULL); u32 partyMonSpecies = GetMonData(partyMon, MON_DATA_SPECIES, NULL); - gBattleMovePower = gMovesInfo[move].power; + gBattleMovePower = GetMovePower(move); - if (IS_MOVE_PHYSICAL(move)) + if (IsBattleMovePhysical(move)) userFinalAttack = GetMonData(partyMon, MON_DATA_ATK, NULL); else userFinalAttack = GetMonData(partyMon, MON_DATA_SPATK, NULL); @@ -10378,7 +10537,7 @@ static u32 GetWeather(void) static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *damageCalcData) { - if (gMovesInfo[damageCalcData->move].effect != EFFECT_FUTURE_SIGHT) + if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT) return FALSE; struct Pokemon *party = GetSideParty(GetBattlerSide(gBattlerAttacker)); @@ -10435,7 +10594,7 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move if (moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED && mod == UQ_4_12(0.0)) mod = UQ_4_12(1.0); - if (gMovesInfo[move].effect == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == gMovesInfo[move].argument) + if (GetMoveEffect(move) == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == GetMoveArgType(move)) mod = UQ_4_12(2.0); if (moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(battlerDef) && mod == UQ_4_12(0.0)) mod = UQ_4_12(1.0); @@ -10512,13 +10671,13 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov if (recordAbilities && (illusionSpecies = GetIllusionMonSpecies(battlerDef))) TryNoticeIllusionInTypeEffectiveness(move, moveType, battlerAtk, battlerDef, modifier, illusionSpecies); - if (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS && move != MOVE_THUNDER_WAVE) + if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS && move != MOVE_THUNDER_WAVE) { modifier = UQ_4_12(1.0); if (B_GLARE_GHOST < GEN_4 && move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST)) modifier = UQ_4_12(0.0); } - else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded)) + else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(MoveIgnoresTypeIfFlyingAndUngrounded(move))) { modifier = UQ_4_12(0.0); if (recordAbilities && defAbility == ABILITY_LEVITATE) @@ -10537,7 +10696,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov // Thousand Arrows ignores type modifiers for flying mons if (!IsBattlerGrounded(battlerDef) - && (gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded) + && MoveIgnoresTypeIfFlyingAndUngrounded(move) && IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING)) { modifier = UQ_4_12(1.0); @@ -10545,7 +10704,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov if (((defAbility == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0)) || (defAbility == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk))) - && gMovesInfo[move].power) + && GetMovePower(move) != 0) { modifier = UQ_4_12(0.0); if (recordAbilities) @@ -10572,8 +10731,8 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier, defAbility); - if (gMovesInfo[move].effect == EFFECT_TWO_TYPED_MOVE) - modifier = CalcTypeEffectivenessMultiplierInternal(move, gMovesInfo[move].argument, battlerAtk, battlerDef, recordAbilities, modifier, defAbility); + if (GetMoveEffect(move) == EFFECT_TWO_TYPED_MOVE) + modifier = CalcTypeEffectivenessMultiplierInternal(move, GetMoveArgType(move), battlerAtk, battlerDef, recordAbilities, modifier, defAbility); } if (recordAbilities) @@ -10584,7 +10743,7 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef) { uq4_12_t modifier = UQ_4_12(1.0); - u32 moveType = GetMoveType(move); + u32 moveType = GetBattleMoveType(move); if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { @@ -10594,7 +10753,7 @@ uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 a if (moveType == TYPE_GROUND && abilityDef == ABILITY_LEVITATE && !(gFieldStatuses & STATUS_FIELD_GRAVITY)) modifier = UQ_4_12(0.0); - if (abilityDef == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0) && gMovesInfo[move].power) + if (abilityDef == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0) && GetMovePower(move) != 0) modifier = UQ_4_12(0.0); } @@ -10617,7 +10776,7 @@ static uq4_12_t GetInverseTypeMultiplier(uq4_12_t multiplier) } } -uq4_12_t GetTypeEffectiveness(struct Pokemon *mon, u8 moveType) +uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType) { uq4_12_t modifier = UQ_4_12(1.0); u16 abilityDef = GetMonAbility(mon); @@ -11182,7 +11341,7 @@ bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, u32 battler) static u32 SwapMoveDamageCategory(u32 move) { - if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL) + if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL) return DAMAGE_CATEGORY_SPECIAL; return DAMAGE_CATEGORY_PHYSICAL; } @@ -11194,11 +11353,11 @@ u8 GetBattleMoveCategory(u32 moveId) if (gBattleStruct != NULL && (IsZMove(moveId) || IsMaxMove(moveId))) // TODO: Might be buggy depending on when this is called. return gBattleStruct->categoryOverride; if (B_PHYSICAL_SPECIAL_SPLIT >= GEN_4) - return gMovesInfo[moveId].category; + return GetMoveCategory(moveId); - if (IS_MOVE_STATUS(moveId)) + if (IsBattleMoveStatus(moveId)) return DAMAGE_CATEGORY_STATUS; - return gTypesInfo[GetMoveType(moveId)].damageCategory; + return gTypesInfo[GetBattleMoveType(moveId)].damageCategory; } static bool32 TryRemoveScreens(u32 battler) @@ -11261,7 +11420,7 @@ static u32 GetFlingPowerFromItemId(u32 itemId) { if (itemId >= ITEM_TM01 && itemId <= ITEM_HM08) { - u32 power = gMovesInfo[ItemIdToBattleMoveId(itemId)].power; + u32 power = GetMovePower(ItemIdToBattleMoveId(itemId)); if (power > 1) return power; return 10; // Status moves and moves with variable power always return 10 power. @@ -11578,17 +11737,18 @@ u32 GetBattlerMoveTargetType(u32 battler, u32 move) { if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(battler, TYPE_GHOST)) return MOVE_TARGET_USER; - if (gMovesInfo[move].effect == EFFECT_EXPANDING_FORCE && IsBattlerTerrainAffected(battler, STATUS_FIELD_PSYCHIC_TERRAIN)) + u32 effect = GetMoveEffect(move); + if (effect == EFFECT_EXPANDING_FORCE && IsBattlerTerrainAffected(battler, STATUS_FIELD_PSYCHIC_TERRAIN)) return MOVE_TARGET_BOTH; - if (gMovesInfo[move].effect == EFFECT_TERA_STARSTORM && gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR) + if (effect == EFFECT_TERA_STARSTORM && gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR) return MOVE_TARGET_BOTH; - return gMovesInfo[move].target; + return GetMoveTarget(move); } bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move) { - if (gMovesInfo[move].effect == EFFECT_HIT_ENEMY_HEAL_ALLY + if (GetMoveEffect(move) == EFFECT_HIT_ENEMY_HEAL_ALLY && GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef) && gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff @@ -11715,10 +11875,11 @@ bool32 IsGen6ExpShareEnabled(void) bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect) { u32 i; - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect - && gMovesInfo[move].additionalEffects[i].self == FALSE) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + if (additionalEffect->moveEffect == moveEffect && additionalEffect->self == FALSE) return TRUE; } return FALSE; @@ -11727,10 +11888,11 @@ bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect) bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance) { u32 i; - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect - && gMovesInfo[move].additionalEffects[i].chance == chance) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + if (additionalEffect->moveEffect == moveEffect && additionalEffect->chance == chance) return TRUE; } return FALSE; @@ -11739,26 +11901,28 @@ bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance) bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect) { u32 i; - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect - && gMovesInfo[move].additionalEffects[i].self == TRUE) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + if (additionalEffect->moveEffect == moveEffect && additionalEffect->self == TRUE) return TRUE; } return FALSE; } -bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument) +bool32 IsMoveEffectRemoveSpeciesType(u32 move, u32 moveEffect, u32 argument) { - return (gMovesInfo[move].argument == argument) && MoveHasAdditionalEffectSelf(move, moveEffect); + return (GetMoveArgType(move) == argument) && MoveHasAdditionalEffectSelf(move, moveEffect); } bool32 MoveHasChargeTurnAdditionalEffect(u32 move) { u32 i; - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].onChargeTurnOnly) + if (GetMoveAdditionalEffectById(move, i)->onChargeTurnOnly) return TRUE; } return FALSE; @@ -11767,9 +11931,16 @@ bool32 MoveHasChargeTurnAdditionalEffect(u32 move) bool32 MoveIsAffectedBySheerForce(u32 move) { u32 i; - for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++) + u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move); + for (i = 0; i < numAdditionalEffects; i++) { - if (gMovesInfo[move].additionalEffects[i].chance > 0) + const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); + if (additionalEffect->sheerForceBoost == SHEER_FORCE_NO_BOOST) + continue; + + if (additionalEffect->chance > 0) + return TRUE; + if (additionalEffect->sheerForceBoost == SHEER_FORCE_BOOST) return TRUE; } return FALSE; @@ -11885,6 +12056,7 @@ void SetShellSideArmCategory(void) u8 statStage; u32 physical; u32 special; + u32 power = GetMovePower(MOVE_SHELL_SIDE_ARM); for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++) { @@ -11908,14 +12080,14 @@ void SetShellSideArmCategory(void) targetDefStat *= gStatStageRatios[statStage][0]; targetDefStat /= gStatStageRatios[statStage][1]; - physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * gMovesInfo[MOVE_SHELL_SIDE_ARM].power * attackerAtkStat) / targetDefStat) / 50); + physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerAtkStat) / targetDefStat) / 50); targetSpDefStat = gBattleMons[battlerDef].spDefense; statStage = gBattleMons[battlerDef].statStages[STAT_SPDEF]; targetSpDefStat *= gStatStageRatios[statStage][0]; targetSpDefStat /= gStatStageRatios[statStage][1]; - special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * gMovesInfo[MOVE_SHELL_SIDE_ARM].power * attackerSpAtkStat) / targetSpDefStat) / 50); + special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerSpAtkStat) / targetSpDefStat) / 50); if ((physical > special) || (physical == special && RandomPercentage(RNG_SHELL_SIDE_ARM, 50))) gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] = DAMAGE_CATEGORY_PHYSICAL; @@ -11940,13 +12112,13 @@ static inline bool32 DoesBattlerHaveAbilityImmunity(u32 battlerDef) bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef) { - return ((CalcTypeEffectivenessMultiplier(gCurrentMove, GetMoveType(gCurrentMove), battlerAtk, battlerDef, GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0)) + return ((CalcTypeEffectivenessMultiplier(gCurrentMove, GetBattleMoveType(gCurrentMove), battlerAtk, battlerDef, GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0)) || IsBattlerProtected(battlerAtk, battlerDef, gCurrentMove) || IsSemiInvulnerable(battlerDef, gCurrentMove) || DoesBattlerHaveAbilityImmunity(battlerDef)); } -u32 GetMoveType(u32 move) +u32 GetBattleMoveType(u32 move) { if (gMain.inBattle && gBattleStruct->dynamicMoveType) return gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK; @@ -11955,7 +12127,7 @@ u32 GetMoveType(u32 move) || move == MOVE_FUTURE_SIGHT || move == MOVE_DOOM_DESIRE)) return TYPE_MYSTERY; - return gMovesInfo[move].type; + return GetMoveType(move); } void TryActivateSleepClause(u32 battler, u32 indexInParty) @@ -12017,8 +12189,25 @@ void ClearDamageCalcResults(void) bool32 DoesDestinyBondFail(u32 battler) { if (B_DESTINY_BOND_FAIL >= GEN_7 - && gMovesInfo[gLastResultingMoves[battler]].effect == EFFECT_DESTINY_BOND + && GetMoveEffect(gLastResultingMoves[battler]) == EFFECT_DESTINY_BOND && !(gBattleStruct->lastMoveFailed & (1u << battler))) return TRUE; return FALSE; } + +// This check has always to be the last in a condtion statement because of the recording of AI data. +bool32 IsMoveEffectBlockedByTarget(u32 ability) +{ + if (ability == ABILITY_SHIELD_DUST) + { + RecordAbilityBattle(gBattlerTarget, ability); + return TRUE; + } + else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_COVERT_CLOAK) + { + RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_COVERT_CLOAK); + return TRUE; + } + + return FALSE; +} diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 53a39b6a79..c878a2c12b 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -151,7 +151,7 @@ u32 GetUsableZMove(u32 battler, u32 move) if (zMove != MOVE_NONE) return zMove; // Signature z move exists - if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && gMovesInfo[move].type == ItemId_GetSecondaryId(item)) + if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && GetMoveType(move) == ItemId_GetSecondaryId(item)) return GetTypeBasedZMove(move); } @@ -195,7 +195,7 @@ bool32 IsViableZMove(u32 battler, u32 move) if (zMove != MOVE_NONE) return TRUE; - if (move != MOVE_NONE && gMovesInfo[move].type == ItemId_GetSecondaryId(item)) + if (move != MOVE_NONE && GetMoveType(move) == ItemId_GetSecondaryId(item)) return TRUE; } @@ -243,13 +243,13 @@ u32 GetSignatureZMove(u32 move, u32 species, u32 item) u32 GetTypeBasedZMove(u32 move) { - u32 moveType = gMovesInfo[move].type; + u32 moveType = GetMoveType(move); if (moveType >= NUMBER_OF_MON_TYPES) moveType = TYPE_MYSTERY; // Z-Weather Ball changes types, however Revelation Dance, -ate ability affected moves, and Hidden Power do not - if (gBattleStruct->dynamicMoveType && gMovesInfo[move].effect == EFFECT_WEATHER_BALL) + if (gBattleStruct->dynamicMoveType && GetMoveEffect(move) == EFFECT_WEATHER_BALL) moveType = gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK; // Get Z-Move from type @@ -276,9 +276,9 @@ bool32 MoveSelectionDisplayZMove(u16 zmove, u32 battler) BattlePutTextOnWindow(gDisplayedStringBattle, i + 3); } - if (IS_MOVE_STATUS(move)) + if (IsBattleMoveStatus(move)) { - u8 zEffect = gMovesInfo[move].zMove.effect; + u8 zEffect = GetMoveZEffect(move); gDisplayedStringBattle[0] = EOS; @@ -388,9 +388,9 @@ static void ZMoveSelectionDisplayPower(u16 move, u16 zMove) u16 power = GetZMovePower(move); if (zMove >= MOVE_CATASTROPIKA) - power = gMovesInfo[zMove].power; + power = GetMovePower(zMove); - if (gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS) + if (GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS) { txtPtr = StringCopy(gDisplayedStringBattle, sText_PowerColon); ConvertIntToDecimalStringN(txtPtr, power, STR_CONV_MODE_LEFT_ALIGN, 3); @@ -415,7 +415,7 @@ static void ZMoveSelectionDisplayPpNumber(u32 battler) static void ZMoveSelectionDisplayMoveType(u16 zMove, u32 battler) { u8 *txtPtr, *end; - u32 zMoveType = GetMoveType(zMove); + u32 zMoveType = GetBattleMoveType(zMove); txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType); *(txtPtr)++ = EXT_CTRL_CODE_BEGIN; @@ -433,7 +433,7 @@ static void ZMoveSelectionDisplayMoveType(u16 zMove, u32 battler) void SetZEffect(void) { u32 i; - u32 effect = gMovesInfo[gBattleStruct->zmove.baseMoves[gBattlerAttacker]].zMove.effect; + u32 effect = GetMoveZEffect(gBattleStruct->zmove.baseMoves[gBattlerAttacker]); if (effect == Z_EFFECT_CURSE) { @@ -542,35 +542,25 @@ void SetZEffect(void) u32 GetZMovePower(u32 move) { - if (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS) + if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS) return 0; - if (gMovesInfo[move].effect == EFFECT_OHKO) + if (GetMoveEffect(move) == EFFECT_OHKO) return 180; - if (gMovesInfo[move].zMove.powerOverride > 0) - return gMovesInfo[move].zMove.powerOverride; - else - { - if (gMovesInfo[move].power >= 140) - return 200; - else if (gMovesInfo[move].power >= 130) - return 195; - else if (gMovesInfo[move].power >= 120) - return 190; - else if (gMovesInfo[move].power >= 110) - return 185; - else if (gMovesInfo[move].power >= 100) - return 180; - else if (gMovesInfo[move].power >= 90) - return 175; - else if (gMovesInfo[move].power >= 80) - return 160; - else if (gMovesInfo[move].power >= 70) - return 140; - else if (gMovesInfo[move].power >= 60) - return 120; - else - return 100; - } + u32 power = GetMoveZPowerOverride(move); + if (power > 0) + return power; + + power = GetMovePower(move); + if (power >= 140) return 200; + else if (power >= 130) return 195; + else if (power >= 120) return 190; + else if (power >= 110) return 185; + else if (power >= 100) return 180; + else if (power >= 90) return 175; + else if (power >= 80) return 160; + else if (power >= 70) return 140; + else if (power >= 60) return 120; + else return 100; } diff --git a/src/caps.c b/src/caps.c index 9c30e55527..941509c2a4 100644 --- a/src/caps.c +++ b/src/caps.c @@ -54,7 +54,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue) if (B_LEVEL_CAP_EXP_UP) { levelDifference = currentLevelCap - level; - if (levelDifference > ARRAY_COUNT(sExpScalingUp)) + if (levelDifference > ARRAY_COUNT(sExpScalingUp) - 1) return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]); else return expValue + (expValue / sExpScalingUp[levelDifference]); @@ -71,7 +71,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue) else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT) { levelDifference = level - currentLevelCap; - if (levelDifference > ARRAY_COUNT(sExpScalingDown)) + if (levelDifference > ARRAY_COUNT(sExpScalingDown) - 1) return expValue / sExpScalingDown[ARRAY_COUNT(sExpScalingDown) - 1]; else return expValue / sExpScalingDown[levelDifference]; diff --git a/src/contest.c b/src/contest.c index f740b46b62..a1cd62777f 100644 --- a/src/contest.c +++ b/src/contest.c @@ -1639,7 +1639,7 @@ static void Task_ShowMoveSelectScreen(u8 taskId) } else if (move != MOVE_NONE && eContestantStatus[gContestPlayerMonIndex].prevMove == move - && gMovesInfo[move].contestEffect != CONTEST_EFFECT_REPETITION_NOT_BORING) + && GetMoveContestEffect(move) != CONTEST_EFFECT_REPETITION_NOT_BORING) { // Gray the text because it's a repeated move moveNameBuffer = StringCopy(moveName, gText_ColorBlue); @@ -2310,7 +2310,7 @@ static void Task_DoAppeals(u8 taskId) } else { - StringCopy(gStringVar3, sContestConditions[gMovesInfo[eContestantStatus[contestant].currMove].contestCategory]); + StringCopy(gStringVar3, sContestConditions[GetMoveContestCategory(eContestantStatus[contestant].currMove)]); } if (r3 > 0 && eContestantStatus[contestant].repeatedMove) @@ -3267,7 +3267,7 @@ static u16 GetMoveEffectSymbolTileOffset(u16 move, u8 contestant) { u16 offset; - switch (gContestEffects[gMovesInfo[move].contestEffect].effectType) + switch (gContestEffects[GetMoveContestEffect(move)].effectType) { case 0: case 1: @@ -3293,7 +3293,7 @@ static void PrintContestMoveDescription(u16 move) u8 numHearts; // The contest category icon is implemented as a 5x2 group of tiles. - category = gMovesInfo[move].contestCategory; + category = GetMoveContestCategory(move); if (category == CONTEST_CATEGORY_COOL) categoryTile = 0x4040; else if (category == CONTEST_CATEGORY_BEAUTY) @@ -3309,27 +3309,27 @@ static void PrintContestMoveDescription(u16 move) ContestBG_FillBoxWithIncrementingTile(0, categoryTile + 0x10, 0x0b, 0x20, 0x05, 0x01, 0x11, 0x01); // Appeal hearts - if (gContestEffects[gMovesInfo[move].contestEffect].appeal == 0xFF) + if (gContestEffects[GetMoveContestEffect(move)].appeal == 0xFF) numHearts = 0; else - numHearts = gContestEffects[gMovesInfo[move].contestEffect].appeal / 10; + numHearts = gContestEffects[GetMoveContestEffect(move)].appeal / 10; if (numHearts > MAX_CONTEST_MOVE_HEARTS) numHearts = MAX_CONTEST_MOVE_HEARTS; ContestBG_FillBoxWithTile(0, TILE_EMPTY_APPEAL_HEART, 0x15, 0x1f, MAX_CONTEST_MOVE_HEARTS, 0x01, 0x11); ContestBG_FillBoxWithTile(0, TILE_FILLED_APPEAL_HEART, 0x15, 0x1f, numHearts, 0x01, 0x11); // Jam hearts - if (gContestEffects[gMovesInfo[move].contestEffect].jam == 0xFF) + if (gContestEffects[GetMoveContestEffect(move)].jam == 0xFF) numHearts = 0; else - numHearts = gContestEffects[gMovesInfo[move].contestEffect].jam / 10; + numHearts = gContestEffects[GetMoveContestEffect(move)].jam / 10; if (numHearts > MAX_CONTEST_MOVE_HEARTS) numHearts = MAX_CONTEST_MOVE_HEARTS; ContestBG_FillBoxWithTile(0, TILE_EMPTY_JAM_HEART, 0x15, 0x20, MAX_CONTEST_MOVE_HEARTS, 0x01, 0x11); ContestBG_FillBoxWithTile(0, TILE_FILLED_JAM_HEART, 0x15, 0x20, numHearts, 0x01, 0x11); FillWindowPixelBuffer(WIN_MOVE_DESCRIPTION, PIXEL_FILL(0)); - Contest_PrintTextToBg0WindowStd(WIN_MOVE_DESCRIPTION, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect]); + Contest_PrintTextToBg0WindowStd(WIN_MOVE_DESCRIPTION, gContestEffectDescriptionPointers[GetMoveContestEffect(move)]); Contest_PrintTextToBg0WindowStd(WIN_SLASH, gText_Slash); } @@ -4530,9 +4530,9 @@ static void CalculateAppealMoveImpact(u8 contestant) return; move = eContestantStatus[contestant].currMove; - effect = gMovesInfo[move].contestEffect; + effect = GetMoveContestEffect(move); - eContestantStatus[contestant].moveCategory = gMovesInfo[eContestantStatus[contestant].currMove].contestCategory; + eContestantStatus[contestant].moveCategory = GetMoveContestCategory(eContestantStatus[contestant].currMove); if (eContestantStatus[contestant].currMove == eContestantStatus[contestant].prevMove && eContestantStatus[contestant].currMove != MOVE_NONE) { eContestantStatus[contestant].repeatedMove = TRUE; @@ -4583,7 +4583,7 @@ static void CalculateAppealMoveImpact(u8 contestant) } else { - if (gMovesInfo[eContestantStatus[contestant].currMove].contestComboStarterId != 0) + if (GetMoveContestComboStarter(eContestantStatus[contestant].currMove) != 0) { eContestantStatus[contestant].hasJudgesAttention = TRUE; eContestantStatus[contestant].usedComboMove = TRUE; @@ -4663,13 +4663,13 @@ static void PrintAppealMoveResultText(u8 contestant, u8 stringId) { StringCopy(gStringVar1, gContestMons[contestant].nickname); StringCopy(gStringVar2, GetMoveName(eContestantStatus[contestant].currMove)); - if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_COOL) + if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_COOL) StringCopy(gStringVar3, gText_Contest_Shyness); - else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_BEAUTY) + else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_BEAUTY) StringCopy(gStringVar3, gText_Contest_Anxiety); - else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_CUTE) + else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_CUTE) StringCopy(gStringVar3, gText_Contest_Laziness); - else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_SMART) + else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_SMART) StringCopy(gStringVar3, gText_Contest_Hesitancy); else StringCopy(gStringVar3, gText_Contest_Fear); @@ -4842,7 +4842,7 @@ static void UpdateApplauseMeter(void) s8 Contest_GetMoveExcitement(u16 move) { - return sContestExcitementTable[gSpecialVar_ContestCategory][gMovesInfo[move].contestCategory]; + return sContestExcitementTable[gSpecialVar_ContestCategory][GetMoveContestCategory(move)]; } static u8 StartApplauseOverflowAnimation(void) diff --git a/src/contest_ai.c b/src/contest_ai.c index f131c709ac..4386aeee64 100644 --- a/src/contest_ai.c +++ b/src/contest_ai.c @@ -758,7 +758,7 @@ static void ContestAICmd_get_move_effect(void) { u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - eContestAI.scriptResult = gMovesInfo[move].contestEffect; + eContestAI.scriptResult = GetMoveContestEffect(move); gAIScriptPtr += 1; } @@ -786,7 +786,7 @@ static void ContestAICmd_get_move_effect_type(void) { u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].effectType; + eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].effectType; gAIScriptPtr += 1; } @@ -814,12 +814,12 @@ static void ContestAICmd_check_most_appealing_move(void) { int i; u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - u8 appeal = gContestEffects[gMovesInfo[move].contestEffect].appeal; + u8 appeal = gContestEffects[GetMoveContestEffect(move)].appeal; for (i = 0; i < MAX_MON_MOVES; i++) { u16 newMove = gContestMons[eContestAI.contestantId].moves[i]; - if (newMove != 0 && appeal < gContestEffects[gMovesInfo[newMove].contestEffect].appeal) + if (newMove != 0 && appeal < gContestEffects[GetMoveContestEffect(newMove)].appeal) break; } @@ -845,12 +845,12 @@ static void ContestAICmd_check_most_jamming_move(void) { int i; u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - u8 jam = gContestEffects[gMovesInfo[move].contestEffect].jam; + u8 jam = gContestEffects[GetMoveContestEffect(move)].jam; for (i = 0; i < MAX_MON_MOVES; i++) { u16 newMove = gContestMons[eContestAI.contestantId].moves[i]; - if (newMove != MOVE_NONE && jam < gContestEffects[gMovesInfo[newMove].contestEffect].jam) + if (newMove != MOVE_NONE && jam < gContestEffects[GetMoveContestEffect(newMove)].jam) break; } @@ -876,7 +876,7 @@ static void ContestAICmd_get_num_move_hearts(void) { u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].appeal / 10; + eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].appeal / 10; gAIScriptPtr += 1; } @@ -924,7 +924,7 @@ static void ContestAICmd_get_num_move_jam_hearts(void) { u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex]; - eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].jam / 10; + eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].jam / 10; gAIScriptPtr += 1; } @@ -1203,7 +1203,7 @@ static void ContestAICmd_get_used_combo_starter(void) u8 contestant = GetContestantIdByTurn(gAIScriptPtr[1]); if (IsContestantAllowedToCombo(contestant)) - result = gMovesInfo[eContestantStatus[contestant].prevMove].contestComboStarterId ? TRUE : FALSE; + result = GetMoveContestComboStarter(eContestantStatus[contestant].prevMove) ? TRUE : FALSE; eContestAI.scriptResult = result; gAIScriptPtr += 2; @@ -1409,7 +1409,7 @@ static void ContestAICmd_get_used_moves_effect(void) u8 round = gAIScriptPtr[2]; u16 move = eContest.moveHistory[round][contestant]; - eContestAI.scriptResult = gMovesInfo[move].contestEffect; + eContestAI.scriptResult = GetMoveContestEffect(move); gAIScriptPtr += 3; } @@ -1509,7 +1509,7 @@ static void ContestAICmd_get_used_moves_effect_type(void) u8 round = gAIScriptPtr[2]; u16 move = eContest.moveHistory[round][contestant]; - eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].effectType; + eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].effectType; gAIScriptPtr += 3; } @@ -1748,7 +1748,7 @@ static void ContestAICmd_check_user_has_move(void) for (i = 0; i < MAX_MON_MOVES; i++) { #ifdef BUGFIX - u16 move = gMovesInfo[gContestMons[eContestAI.contestantId].moves[i]].contestEffect; + u16 move = GetMoveContestEffect(gContestMons[eContestAI.contestantId].moves[i]); #else u16 move = gContestMons[eContestAI.contestantId].moves[i]; #endif diff --git a/src/contest_effect.c b/src/contest_effect.c index 0de31339f4..51416ba14a 100644 --- a/src/contest_effect.c +++ b/src/contest_effect.c @@ -1,4 +1,5 @@ #include "global.h" +#include "move.h" #include "random.h" #include "constants/moves.h" #include "contest.h" @@ -60,7 +61,7 @@ static s16 RoundUp(s16); bool8 AreMovesContestCombo(u16 lastMove, u16 nextMove) { int i; - u8 lastMoveComboStarterId = gMovesInfo[lastMove].contestComboStarterId; + u8 lastMoveComboStarterId = GetMoveContestComboStarter(lastMove); if (lastMoveComboStarterId == 0) { @@ -70,7 +71,7 @@ bool8 AreMovesContestCombo(u16 lastMove, u16 nextMove) { for (i = 0; i < MAX_COMBO_MOVES; i++) { - if (lastMoveComboStarterId == gMovesInfo[nextMove].contestComboMoves[i]) + if (lastMoveComboStarterId == GetMoveContestComboMoves(nextMove, i)) return TRUE; } return FALSE; @@ -132,7 +133,7 @@ static void ContestEffect_UserLessEasilyStartled(void) SetContestantEffectStringID(eContestAppealResults.contestant,CONTEST_STRING_STOPPED_CARING); } -// Slightly startles the POKMON in front. +// Slightly startles the POK�MON in front. static void ContestEffect_StartleFrontMon(void) { u8 idx = 0; @@ -180,7 +181,7 @@ static void ContestEffect_StartlePrevMons(void) SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Startles the POKMON that appealed before the user. +// Startles the POK�MON that appealed before the user. static void ContestEffect_StartlePrevMon2(void) { u8 rval = Random() % 10; @@ -197,7 +198,7 @@ static void ContestEffect_StartlePrevMon2(void) ContestEffect_StartleFrontMon(); } -// Startles all POKMON that appealed before the user. +// Startles all POK�MON that appealed before the user. static void ContestEffect_StartlePrevMons2(void) { u8 numStartled = 0; @@ -273,7 +274,7 @@ static void ContestEffect_ShiftJudgeAttention(void) } } -// Startles the POKMON that has the JUDGE's attention. +// Startles the POK�MON that has the JUDGE's attention. static void ContestEffect_StartleMonWithJudgesAttention(void) { u8 numStartled = 0; @@ -311,50 +312,50 @@ static void ContestEffect_JamsOthersButMissOneTurn(void) SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Startles POKMON that made a same-type appeal. +// Startles POK�MON that made a same-type appeal. static void ContestEffect_StartleMonsSameTypeAppeal(void) { u16 move = eContestantStatus[eContestAppealResults.contestant].currMove; - JamByMoveCategory(gMovesInfo[move].contestCategory); + JamByMoveCategory(GetMoveContestCategory(move)); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Badly startles POKMON that made COOL appeals. +// Badly startles POK�MON that made COOL appeals. static void ContestEffect_StartleMonsCoolAppeal(void) { JamByMoveCategory(CONTEST_CATEGORY_COOL); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Badly startles POKMON that made BEAUTY appeals. +// Badly startles POK�MON that made BEAUTY appeals. static void ContestEffect_StartleMonsBeautyAppeal(void) { JamByMoveCategory(CONTEST_CATEGORY_BEAUTY); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Badly startles POKMON that made CUTE appeals. +// Badly startles POK�MON that made CUTE appeals. static void ContestEffect_StartleMonsCuteAppeal(void) { JamByMoveCategory(CONTEST_CATEGORY_CUTE); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Badly startles POKMON that made SMART appeals. +// Badly startles POK�MON that made SMART appeals. static void ContestEffect_StartleMonsSmartAppeal(void) { JamByMoveCategory(CONTEST_CATEGORY_SMART); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Badly startles POKMON that made TOUGH appeals. +// Badly startles POK�MON that made TOUGH appeals. static void ContestEffect_StartleMonsToughAppeal(void) { JamByMoveCategory(CONTEST_CATEGORY_TOUGH); SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE); } -// Makes one POKMON after the user nervous. +// Makes one POK�MON after the user nervous. static void ContestEffect_MakeFollowingMonNervous(void) { bool32 hitAny = FALSE; @@ -386,7 +387,7 @@ static void ContestEffect_MakeFollowingMonNervous(void) SetContestantEffectStringID2(eContestAppealResults.contestant, CONTEST_STRING_MESSED_UP2); } -// Makes all POKMON after the user nervous. +// Makes all POK�MON after the user nervous. static void ContestEffect_MakeFollowingMonsNervous(void) { u8 numUnnerved = 0; @@ -428,7 +429,7 @@ static void ContestEffect_MakeFollowingMonsNervous(void) for (i = 0; i < CONTESTANT_COUNT; i++) { if (eContestantStatus[i].hasJudgesAttention && IsContestantAllowedToCombo(i)) - oddsMod[i] = gMovesInfo[eContestantStatus[i].prevMove].contestComboStarterId == 0 ? 0 : 10; + oddsMod[i] = GetMoveContestComboStarter(eContestantStatus[i].prevMove) == 0 ? 0 : 10; else oddsMod[i] = 0; oddsMod[i] -= (eContestantStatus[i].condition / 10) * 10; @@ -493,7 +494,7 @@ static void ContestEffect_WorsenConditionOfPrevMons(void) SetContestantEffectStringID2(eContestAppealResults.contestant, CONTEST_STRING_IGNORED); } -// Badly startles POKMON in good condition. +// Badly startles POK�MON in good condition. static void ContestEffect_BadlyStartlesMonsInGoodCondition(void) { u8 numHit = 0; @@ -524,7 +525,7 @@ static void ContestEffect_BetterIfFirst(void) if (gContestantTurnOrder[eContestAppealResults.contestant] == 0) { u16 move = eContestantStatus[eContestAppealResults.contestant].currMove; - eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[gMovesInfo[move].contestEffect].appeal; + eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[GetMoveContestEffect(move)].appeal; SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_HUSTLE_STANDOUT); } } @@ -535,7 +536,7 @@ static void ContestEffect_BetterIfLast(void) if (gContestantTurnOrder[eContestAppealResults.contestant] == 3) { u16 move = eContestantStatus[eContestAppealResults.contestant].currMove; - eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[gMovesInfo[move].contestEffect].appeal; + eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[GetMoveContestEffect(move)].appeal; SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_WORK_HARD_UNNOTICED); } } @@ -671,9 +672,9 @@ static void ContestEffect_BetterIfSameType(void) } move = eContestantStatus[eContestAppealResults.contestant].currMove; - if (gMovesInfo[move].contestCategory == gMovesInfo[eContestantStatus[j].currMove].contestCategory) + if (GetMoveContestCategory(move) == GetMoveContestCategory(eContestantStatus[j].currMove)) { - eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[gMovesInfo[move].contestEffect].appeal * 2; + eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[GetMoveContestEffect(move)].appeal * 2; SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_SAME_TYPE_GOOD); } } @@ -689,9 +690,9 @@ static void ContestEffect_BetterIfDiffType(void) for (i = 0; i < CONTESTANT_COUNT; i++) { if (eContestAppealResults.turnOrder[eContestAppealResults.contestant] - 1 == eContestAppealResults.turnOrder[i] && - gMovesInfo[move].contestCategory != gMovesInfo[eContestantStatus[i].currMove].contestCategory) + GetMoveContestCategory(move) != GetMoveContestCategory(eContestantStatus[i].currMove)) { - eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[gMovesInfo[move].contestEffect].appeal * 2; + eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[GetMoveContestEffect(move)].appeal * 2; SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_DIFF_TYPE_GOOD); break; } @@ -891,13 +892,13 @@ static void ContestEffect_ScrambleNextTurnOrder(void) // An appeal that excites the audience in any CONTEST. static void ContestEffect_ExciteAudienceInAnyContest(void) { - if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory != gSpecialVar_ContestCategory) + if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) != gSpecialVar_ContestCategory) { eContestantStatus[eContestAppealResults.contestant].overrideCategoryExcitementMod = TRUE; } } -// Badly startles all POKMON that made good appeals. +// Badly startles all POK�MON that made good appeals. static void ContestEffect_BadlyStartleMonsWithGoodAppeals(void) { int i; @@ -980,7 +981,7 @@ static void JamByMoveCategory(u8 category) { if (eContestAppealResults.turnOrder[eContestAppealResults.contestant] > eContestAppealResults.turnOrder[i]) { - if (category == gMovesInfo[eContestantStatus[i].currMove].contestCategory) + if (category == GetMoveContestCategory(eContestantStatus[i].currMove)) eContestAppealResults.jam = 40; else eContestAppealResults.jam = 10; diff --git a/src/crt0.s b/src/crt0.s index af6ea0bc95..bd0eb9426c 100644 --- a/src/crt0.s +++ b/src/crt0.s @@ -14,15 +14,15 @@ Init:: mov r0, #PSR_SYS_MODE msr cpsr_cf, r0 ldr sp, sp_sys -@ Prepare for interrupt handling - ldr r1, =INTR_VECTOR - adr r0, IntrMain - str r0, [r1] @ Dispatch memory reset request to hardware mov r0, #255 @ RESET_ALL svc #1 << 16 @ Fill RAM areas with appropriate data bl InitializeWorkingMemory +@ Prepare for interrupt handling + ldr r1, =INTR_VECTOR + ldr r0, =IntrMain + str r0, [r1] @ Jump to AgbMain ldr r1, =AgbMain + 1 mov lr, pc @@ -37,6 +37,7 @@ sp_irq: .word IWRAM_END - 0x60 .pool .arm + .section .iwram.code .align 2, 0 IntrMain:: mov r3, #REG_BASE @@ -129,6 +130,7 @@ IntrMain_RetAddr: .pool + .text .align 2, 0 @ Don't pad with nop. @ Fills initialized IWRAM and EWRAM sections in RAM from LMA areas in ROM diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index ab70de3681..b9fcdd59f6 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -1832,12 +1832,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_EERIE_SPELL] = - { - .battleScript = BattleScript_EffectEerieSpell, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_JUNGLE_HEALING] = { .battleScript = BattleScript_EffectJungleHealing, @@ -1901,42 +1895,12 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_GLITZY_GLOW] = - { - .battleScript = BattleScript_EffectGlitzyGlow, - .battleTvScore = 0, // TODO: Assign points - }, - - [EFFECT_BADDY_BAD] = - { - .battleScript = BattleScript_EffectBaddyBad, - .battleTvScore = 0, // TODO: Assign points - }, - - [EFFECT_SAPPY_SEED] = - { - .battleScript = BattleScript_EffectSappySeed, - .battleTvScore = 0, // TODO: Assign points - }, - - [EFFECT_FREEZY_FROST] = - { - .battleScript = BattleScript_EffectFreezyFrost, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_SPARKLY_SWIRL] = { .battleScript = BattleScript_EffectSparklySwirl, .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_PLASMA_FISTS] = - { - .battleScript = BattleScript_EffectPlasmaFists, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_HYPERSPACE_FURY] = { .battleScript = BattleScript_EffectHyperspaceFury, @@ -2134,12 +2098,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_SALT_CURE] = - { - .battleScript = BattleScript_EffectSaltCure, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_CHILLY_RECEPTION] = { .battleScript = BattleScript_EffectChillyReception, diff --git a/src/data/field_effects/field_effect_object_template_pointers.h b/src/data/field_effects/field_effect_object_template_pointers.h index 6c1b3a3946..7173ffbe58 100755 --- a/src/data/field_effects/field_effect_object_template_pointers.h +++ b/src/data/field_effects/field_effect_object_template_pointers.h @@ -39,6 +39,7 @@ extern const struct SpriteTemplate gFieldEffectObjectTemplate_BallLight; extern const struct SpriteTemplate gFieldEffectObjectTemplate_SlitherTracks; extern const struct SpriteTemplate gFieldEffectObjectTemplate_BugTracks; extern const struct SpriteTemplate gFieldEffectObjectTemplate_SpotTracks; +extern const struct SpriteTemplate gFieldEffectObjectTemplate_CaveDust; const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[] = { [FLDEFFOBJ_SHADOW_S] = &gFieldEffectObjectTemplate_ShadowSmall, @@ -81,4 +82,5 @@ const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[] = { [FLDEFFOBJ_TRACKS_SLITHER] = &gFieldEffectObjectTemplate_SlitherTracks, [FLDEFFOBJ_TRACKS_SPOT] = &gFieldEffectObjectTemplate_SpotTracks, [FLDEFFOBJ_TRACKS_BUG] = &gFieldEffectObjectTemplate_BugTracks, + [FLDEFFOBJ_CAVE_DUST] = &gFieldEffectObjectTemplate_CaveDust, }; diff --git a/src/data/field_effects/field_effect_objects.h b/src/data/field_effects/field_effect_objects.h index e456ece3b6..95dcbc5b28 100644 --- a/src/data/field_effects/field_effect_objects.h +++ b/src/data/field_effects/field_effect_objects.h @@ -1376,3 +1376,23 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_Rayquaza = { }; static const struct SpritePalette sSpritePalette_Unused = {gObjectEventPal_Npc3, FLDEFF_PAL_TAG_UNKNOWN}; + +// cave dust +static const struct SpriteFrameImage sPicTable_CaveDust[] = +{ + overworld_frame(gFieldEffectObjectPic_CaveDust, 2, 2, 0), + overworld_frame(gFieldEffectObjectPic_CaveDust, 2, 2, 1), + overworld_frame(gFieldEffectObjectPic_CaveDust, 2, 2, 2), + overworld_frame(gFieldEffectObjectPic_CaveDust, 2, 2, 3), +}; +const struct SpriteTemplate gFieldEffectObjectTemplate_CaveDust = { + .tileTag = 0xFFFF, + .paletteTag = FLDEFF_PAL_TAG_CAVE_DUST, + .oam = &gObjectEventBaseOam_16x16, + .anims = sAnimTable_WaterSurfacing, + .images = sPicTable_CaveDust, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = WaitFieldEffectSpriteAnim, +}; + +const struct SpritePalette gSpritePalette_CaveDust = {gFieldEffectObjectPalette_CaveDust, FLDEFF_PAL_TAG_CAVE_DUST}; diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 49d35c0897..2c28621286 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -17,11 +17,6 @@ #define BINDING_TURNS "2 to 5" #endif -/* First arg is the charge turn string id, second arg depends on effect -EFFECT_SEMI_INVULNERABLE/EFFECT_SKY_DROP: semi-invulnerable STATUS3 to apply to battler -EFFECT_TWO_TURNS_ATTACK/EFFECT_SOLAR_BEAM: weather in which to skip charge turn */ -#define TWO_TURN_ARG(stringid, ...) (stringid) __VA_OPT__(| ((__VA_ARGS__) << 16)) - // Shared Move Description entries const u8 gNotDoneYetDescription[] = _( @@ -438,7 +433,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .windMove = B_EXTRAPOLATED_MOVE_FLAGS, - .argument = TWO_TURN_ARG(STRINGID_PKMNWHIPPEDWHIRLWIND), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNWHIPPEDWHIRLWIND }, .contestEffect = CONTEST_EFFECT_AFFECTED_BY_PREV_APPEAL, .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = 0, @@ -586,7 +581,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNFLEWHIGH, COMPRESS_BITS(STATUS3_ON_AIR)), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNFLEWHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -1332,7 +1327,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 20, + .argument = { .fixedDamage = 20 }, .contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE, .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = 0, @@ -1874,7 +1869,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_PREV_MON, @@ -1896,7 +1891,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .zMove = { .powerOverride = 120 }, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -1999,7 +1994,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKSUNLIGHT, B_WEATHER_SUN), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKSUNLIGHT, .status = B_WEATHER_SUN }, .contestEffect = CONTEST_EFFECT_HIGHLY_APPEALING, .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = 0, @@ -2151,7 +2146,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_4) || (B_UPDATED_MOVE_FLAGS < GEN_3), - .argument = 40, + .argument = { .fixedDamage = 40 }, .contestEffect = CONTEST_EFFECT_BETTER_WHEN_LATER, .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = COMBO_STARTER_DRAGON_RAGE, @@ -2370,7 +2365,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .assistBanned = TRUE, .skyBattleBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNDUGHOLE, COMPRESS_BITS(STATUS3_UNDERGROUND)), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNDUGHOLE, .status = COMPRESS_BITS(STATUS3_UNDERGROUND) }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -2986,7 +2981,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_ACC_UP_1 }, - .argument = STATUS2_FOCUS_ENERGY, + .argument = { .status = STATUS2_FOCUS_ENERGY }, .ignoresProtect = TRUE, .mirrorMoveBanned = TRUE, .snatchAffected = TRUE, @@ -3343,7 +3338,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .makesContact = TRUE, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNLOWEREDHEAD), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNLOWEREDHEAD }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_DEF_PLUS_1, .self = TRUE, @@ -3622,7 +3617,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .makesContact = TRUE, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -3673,7 +3668,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .criticalHitStage = B_UPDATED_MOVE_DATA >= GEN_3, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(B_UPDATED_MOVE_DATA >= GEN_4 ? STRINGID_CLOAKEDINAHARSHLIGHT : STRINGID_PKMNISGLOWING), + .argument.twoTurnAttack = { .stringId = B_UPDATED_MOVE_DATA >= GEN_4 ? STRINGID_CLOAKEDINAHARSHLIGHT : STRINGID_PKMNISGLOWING }, #if B_UPDATED_MOVE_DATA >= GEN_3 .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FLINCH, @@ -5155,7 +5150,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, @@ -6735,7 +6730,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = STATUS1_PARALYSIS, + .argument = { .status = STATUS1_PARALYSIS }, .makesContact = TRUE, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_REMOVE_STATUS, @@ -7391,7 +7386,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .assistBanned = TRUE, .skyBattleBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNHIDUNDERWATER, COMPRESS_BITS(STATUS3_UNDERWATER)), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNHIDUNDERWATER, .status = COMPRESS_BITS(STATUS3_UNDERWATER) }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE_ONCE, .contestCategory = CONTEST_CATEGORY_BEAUTY, .contestComboStarterId = COMBO_STARTER_DIVE, @@ -8599,7 +8594,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNSPRANGUP, COMPRESS_BITS(STATUS3_ON_AIR)), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNSPRANGUP, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_PARALYSIS, .chance = 30, @@ -9048,7 +9043,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = STATUS1_SLEEP, + .argument = { .status = STATUS1_SLEEP }, .makesContact = TRUE, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_REMOVE_STATUS, @@ -10268,7 +10263,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .makesContact = TRUE, .punchingMove = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -11272,7 +11267,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = HOLD_EFFECT_PLATE, + .argument = { .holdEffect = HOLD_EFFECT_PLATE }, .contestEffect = CONTEST_EFFECT_SCRAMBLE_NEXT_TURN_ORDER, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -11702,7 +11697,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_VANISHEDINSTANTLY, COMPRESS_BITS(STATUS3_PHANTOM_FORCE)), + .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FEINT, }), @@ -11752,7 +11747,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_USER, .priority = 3, .category = DAMAGE_CATEGORY_STATUS, - .argument = TRUE, // Protects the whole side. + .argument = { .protect.side = TRUE, }, .zMove = { .effect = Z_EFFECT_DEF_UP_1 }, .snatchAffected = TRUE, .ignoresProtect = TRUE, @@ -11867,7 +11862,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = STATUS1_PSN_ANY, + .argument = { .status = STATUS1_PSN_ANY }, .contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE, .contestCategory = CONTEST_CATEGORY_TOUGH, .contestComboStarterId = 0, @@ -12513,7 +12508,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_USER, .priority = 3, .category = DAMAGE_CATEGORY_STATUS, - .argument = TRUE, // Protects the whole side. + .argument = { .protect.side = TRUE, }, .zMove = { .effect = Z_EFFECT_DEF_UP_1 }, .snatchAffected = TRUE, .ignoresProtect = TRUE, @@ -12642,7 +12637,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, .zMove = { .powerOverride = 160 }, - .argument = STATUS1_ANY, + .argument = { .status = STATUS1_ANY }, .contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -12669,7 +12664,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKTARGETHIGH, COMPRESS_BITS(STATUS3_ON_AIR)), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKTARGETHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) }, .contestEffect = CONTEST_EFFECT_AVOID_STARTLE, .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, @@ -13249,7 +13244,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .makesContact = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, @@ -13585,7 +13580,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = HOLD_EFFECT_DRIVE, + .argument = { .holdEffect = HOLD_EFFECT_DRIVE }, .metronomeBanned = TRUE, .contestEffect = CONTEST_EFFECT_EXCITE_AUDIENCE_IN_ANY_CONTEST, .contestCategory = CONTEST_CATEGORY_COOL, @@ -13608,7 +13603,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_BOTH, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = STATUS1_SLEEP, + .argument = { .status = STATUS1_SLEEP }, .ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6, .soundMove = TRUE, .metronomeBanned = TRUE, @@ -13766,7 +13761,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .metronomeBanned = TRUE, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_CLOAKEDINAFREEZINGLIGHT), + .argument.twoTurnAttack = { .stringId = STRINGID_CLOAKEDINAFREEZINGLIGHT }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_PARALYSIS, .chance = 30, @@ -13795,7 +13790,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .metronomeBanned = TRUE, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_CLOAKEDINAFREEZINGLIGHT), + .argument.twoTurnAttack = { .stringId = STRINGID_CLOAKEDINAFREEZINGLIGHT }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_BURN, .chance = 30, @@ -13946,7 +13941,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .zMove = { .powerOverride = 170 }, - .argument = TYPE_FLYING, + .argument = { .type = TYPE_FLYING }, .makesContact = TRUE, .minimizeDoubleDamage = TRUE, .gravityBanned = TRUE, @@ -13972,7 +13967,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_USER, .priority = 0, .category = DAMAGE_CATEGORY_STATUS, - .argument = TRUE, // Protects the whole side. + .argument = { .protect.side = TRUE }, .zMove = { .effect = Z_EFFECT_DEF_UP_1 }, .snatchAffected = TRUE, .ignoresProtect = TRUE, @@ -14108,7 +14103,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .assistBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_VANISHEDINSTANTLY, COMPRESS_BITS(STATUS3_PHANTOM_FORCE)), + .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FEINT, }), @@ -14133,7 +14128,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_STATUS, - .argument = TYPE_GHOST, + .argument = { .type = TYPE_GHOST }, .zMove = { .effect = Z_EFFECT_ALL_STATS_UP_1 }, .magicCoatAffected = TRUE, .contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS, @@ -14206,7 +14201,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_FOES_AND_ALLY, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestCategory = CONTEST_CATEGORY_BEAUTY, @@ -14229,7 +14224,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_STATUS, - .argument = TYPE_GRASS, + .argument = { .type = TYPE_GRASS }, .zMove = { .effect = Z_EFFECT_ALL_STATS_UP_1 }, .magicCoatAffected = TRUE, .contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS, @@ -14279,7 +14274,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = TYPE_WATER, + .argument = { .type = TYPE_WATER }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FREEZE_OR_FROSTBITE, .chance = 10, @@ -14374,7 +14369,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 75, // restores 75% HP instead of 50% HP + .argument = { .absorbPercentage = 75 }, .makesContact = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, @@ -14398,7 +14393,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_USER, .priority = 3, .category = DAMAGE_CATEGORY_STATUS, - .argument = TRUE, // Protects the whole side. + .argument = { .protect.side = TRUE, }, .zMove = { .effect = Z_EFFECT_SPDEF_UP_1 }, .ignoresProtect = TRUE, .mirrorMoveBanned = TRUE, @@ -14970,7 +14965,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .sleepTalkBanned = TRUE, .instructBanned = TRUE, .skyBattleBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKNMABSORBINGPOWER), + .argument.twoTurnAttack = { .stringId = STRINGID_PKNMABSORBINGPOWER }, .contestEffect = CONTEST_EFFECT_IMPROVE_CONDITION_PREVENT_NERVOUSNESS, .contestCategory = CONTEST_CATEGORY_CUTE, .contestComboStarterId = 0, @@ -15268,7 +15263,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 75, // restores 75% HP instead of 50% HP + .argument = { .absorbPercentage = 75 }, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestCategory = CONTEST_CATEGORY_COOL, @@ -15510,7 +15505,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 2, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MOVE_FIRST_IMPRESSION, + .argument = { .moveProperty = MOVE_FIRST_IMPRESSION }, .makesContact = TRUE, .contestEffect = CONTEST_EFFECT_BETTER_IF_FIRST, .contestCategory = CONTEST_CATEGORY_COOL, @@ -15608,7 +15603,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_FOES_AND_ALLY, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = STATUS1_BURN, + .argument = { .status = STATUS1_BURN }, .ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6, .soundMove = TRUE, .additionalEffects = ADDITIONAL_EFFECTS({ @@ -15664,7 +15659,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_RESET_STATS }, - .argument = MOVE_EFFECT_FLORAL_HEALING, + .argument = { .moveProperty = MOVE_EFFECT_FLORAL_HEALING }, .mirrorMoveBanned = TRUE, .healingMove = TRUE, .magicCoatAffected = TRUE, @@ -15739,7 +15734,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .slicingMove = TRUE, .sleepTalkBanned = TRUE, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKSUNLIGHT, B_WEATHER_SUN), + .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKSUNLIGHT, .status = B_WEATHER_SUN }, .contestEffect = CONTEST_EFFECT_HIGHLY_APPEALING, .contestCategory = CONTEST_CATEGORY_TOUGH, .contestComboStarterId = 0, @@ -16056,7 +16051,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, .thawsUser = TRUE, - .argument = TYPE_FIRE, + .argument = { .type = TYPE_FIRE }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_REMOVE_ARG_TYPE, .self = TRUE, @@ -16720,7 +16715,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = HOLD_EFFECT_MEMORY, + .argument = { .holdEffect = HOLD_EFFECT_MEMORY }, .makesContact = TRUE, .contestEffect = CONTEST_EFFECT_SCRAMBLE_NEXT_TURN_ORDER, .contestCategory = CONTEST_CATEGORY_BEAUTY, @@ -16757,7 +16752,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Hits with electrical fists.\n" "Normal moves turn Electric."), - .effect = EFFECT_PLASMA_FISTS, + .effect = EFFECT_HIT, .power = 100, .type = TYPE_ELECTRIC, .accuracy = 100, @@ -16772,6 +16767,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = 0, .contestComboMoves = {0}, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_ION_DELUGE, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_PlasmaFists, }, @@ -16820,6 +16820,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_EVS_PLUS_1, .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, }), #endif .battleAnimScript = gBattleAnimMove_ZippyZap, @@ -16869,6 +16870,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FLINCH, .chance = 30, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, }), .battleAnimScript = gBattleAnimMove_FloatyFall, }, @@ -16910,7 +16912,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 50, // restores 100% HP instead of 50% HP + .argument = { .absorbPercentage = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 50 }, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -16936,6 +16938,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_PARALYSIS, .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, }), .battleAnimScript = gBattleAnimMove_BuzzyBuzz, }, @@ -16961,6 +16964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_BURN, .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, }), .battleAnimScript = gBattleAnimMove_SizzlySlide, }, @@ -16971,7 +16975,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Telekinetic force that sets\n" "wall, lowering Sp. Atk damage."), - .effect = EFFECT_GLITZY_GLOW, + .effect = EFFECT_HIT, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90, .type = TYPE_PSYCHIC, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100, @@ -16981,6 +16985,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_LIGHT_SCREEN, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_GlitzyGlow, }, @@ -16990,7 +16999,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Acting badly, attacks. Sets\n" "wall, lowering Attack damage."), - .effect = EFFECT_BADDY_BAD, + .effect = EFFECT_HIT, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90, .type = TYPE_DARK, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100, @@ -17000,6 +17009,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_REFLECT, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_BaddyBad, }, @@ -17009,7 +17023,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Giant stalk scatters seeds\n" "that drain HP every turn."), - .effect = EFFECT_SAPPY_SEED, + .effect = EFFECT_HIT, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90, .type = TYPE_GRASS, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100, @@ -17020,6 +17034,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .magicCoatAffected = TRUE, .metronomeBanned = TRUE, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_LEECH_SEED, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_SappySeed, }, @@ -17029,7 +17048,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Crystal from cold haze hits.\n" "Eliminates all stat changes."), - .effect = EFFECT_FREEZY_FROST, + .effect = EFFECT_HIT, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90, .type = TYPE_ICE, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100, @@ -17039,6 +17058,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_HAZE, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_FreezyFrost, }, @@ -17048,7 +17072,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Wrap foe with whirlwind of\n" "scent. Heals party's status."), - .effect = EFFECT_SPARKLY_SWIRL, + .effect = EFFECT_SPARKLY_SWIRL, // Temprorary .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 120 : 90, .type = TYPE_FAIRY, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 85 : 100, @@ -17058,6 +17082,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, + // .additionalEffects = ADDITIONAL_EFFECTS({ + // .moveEffect = 0, // MOVE_EFFECT_AROMATHERAPY, Added 0 for Sheer Force boost + // .chance = 100, + // .sheerForceBoost = SHEER_FORCE_NO_BOOST, + // }), .battleAnimScript = gBattleAnimMove_SparklySwirl, }, @@ -17273,7 +17302,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_STATUS, - .argument = TYPE_PSYCHIC, + .argument = { .type = TYPE_PSYCHIC }, .magicCoatAffected = TRUE, .powderMove = TRUE, .contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS, @@ -18019,7 +18048,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, - .argument = ARG_TRY_REMOVE_TERRAIN_FAIL, // Remove a field terrain if there is one and hit, otherwise fail. + .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_FAIL }, // Remove a field terrain if there is one and hit, otherwise fail. .skyBattleBanned = TRUE, .contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS, .contestCategory = CONTEST_CATEGORY_TOUGH, @@ -18042,7 +18071,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MOVE_EFFECT_SCALE_SHOT, + .argument = { .moveProperty = MOVE_EFFECT_SCALE_SHOT }, .contestEffect = CONTEST_EFFECT_NEXT_APPEAL_EARLIER, .contestCategory = CONTEST_CATEGORY_COOL, .contestComboStarterId = 0, @@ -18065,7 +18094,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, .instructBanned = TRUE, - .argument = TWO_TURN_ARG(STRINGID_METEORBEAMCHARGING), + .argument.twoTurnAttack = { .stringId = STRINGID_METEORBEAMCHARGING }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_SP_ATK_PLUS_1, .self = TRUE, @@ -18682,7 +18711,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Attacks with psychic power.\n" "Foe's last move has 3 PP cut."), - .effect = EFFECT_EERIE_SPELL, + .effect = EFFECT_HIT, .power = 80, .type = TYPE_PSYCHIC, .accuracy = 100, @@ -18696,6 +18725,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .contestCategory = CONTEST_CATEGORY_SMART, .contestComboStarterId = 0, .contestComboMoves = {0}, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_EERIE_SPELL, + .chance = 100, + }), .battleAnimScript = gBattleAnimMove_EerieSpell, }, @@ -18971,7 +19004,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = STATUS1_PSN_ANY, + .argument = { .status = STATUS1_PSN_ANY }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_POISON, .chance = 50, @@ -19083,7 +19116,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = STATUS1_ANY, + .argument = { .status = STATUS1_ANY }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_BURN, .chance = 30, @@ -19446,7 +19479,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, - .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one. + .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_HIT }, // Remove the active field terrain if there is one. .skyBattleBanned = B_EXTRAPOLATED_MOVE_FLAGS, .battleAnimScript = gBattleAnimMove_IceSpinner, }, @@ -19497,7 +19530,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Hurts foe every turn. Double\n" "damage to Steel and Water."), - .effect = EFFECT_SALT_CURE, + .effect = EFFECT_HIT, .power = 40, .type = TYPE_ROCK, .accuracy = 100, @@ -19506,6 +19539,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .metronomeBanned = TRUE, + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_SALT_CURE, + .chance = 100, + }), .battleAnimScript = gBattleAnimMove_SaltCure, }, @@ -20028,7 +20065,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .makesContact = TRUE, .slicingMove = TRUE, .healingMove = TRUE, @@ -20051,7 +20088,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, .metronomeBanned = TRUE, - .argument = TYPE_ELECTRIC, + .argument = { .type = TYPE_ELECTRIC }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_REMOVE_ARG_TYPE, .self = TRUE, @@ -20330,7 +20367,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_BOTH, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = 50, + .argument = { .absorbPercentage = 50 }, .thawsUser = TRUE, .metronomeBanned = TRUE, .healingMove = B_EXTRAPOLATED_MOVE_FLAGS, @@ -20397,12 +20434,13 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = TWO_TURN_ARG(STRINGID_ELECTROSHOTCHARGING, B_WEATHER_RAIN), + .argument.twoTurnAttack = { .stringId = STRINGID_ELECTROSHOTCHARGING, .status = B_WEATHER_RAIN }, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_SP_ATK_PLUS_1, .self = TRUE, .onChargeTurnOnly = TRUE, - }, SHEER_FORCE_HACK), + .sheerForceBoost = SHEER_FORCE_BOOST, + }), .battleAnimScript = gBattleAnimMove_ElectroShot, }, @@ -20676,6 +20714,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_TOXIC, .chance = 50, + .sheerForceBoost = SHEER_FORCE_BOOST, }), .battleAnimScript = gBattleAnimMove_MalignantChain, }, @@ -21021,7 +21060,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, - .argument = ARG_SET_PSYCHIC_TERRAIN, // Set Psychic Terrain. If there's a different field terrain active, overwrite it. + .argument = { .moveProperty = ARG_SET_PSYCHIC_TERRAIN }, // Set Psychic Terrain. If there's a different field terrain active, overwrite it. .battleAnimScript = gBattleAnimMove_GenesisSupernova, }, [MOVE_SINISTER_ARROW_RAID] = @@ -21078,7 +21117,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one. + .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_HIT }, // Remove the active field terrain if there is one. .battleAnimScript = gBattleAnimMove_SplinteredStormshards, }, [MOVE_LETS_SNUGGLE_FOREVER] = @@ -21217,7 +21256,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_SUN, + .argument = { .maxEffect = MAX_EFFECT_SUN }, .battleAnimScript = gBattleAnimMove_MaxFlare, }, @@ -21233,7 +21272,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_SP_ATK, + .argument = { .maxEffect = MAX_EFFECT_LOWER_SP_ATK }, .battleAnimScript = gBattleAnimMove_MaxFlutterby, }, @@ -21249,7 +21288,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_ELECTRIC_TERRAIN, + .argument = { .maxEffect = MAX_EFFECT_ELECTRIC_TERRAIN }, .battleAnimScript = gBattleAnimMove_MaxLightning, }, @@ -21265,7 +21304,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_SPEED, + .argument = { .maxEffect = MAX_EFFECT_LOWER_SPEED }, .battleAnimScript = gBattleAnimMove_MaxStrike, }, @@ -21281,7 +21320,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAISE_TEAM_ATTACK, + .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_ATTACK }, .battleAnimScript = gBattleAnimMove_MaxKnuckle, }, @@ -21297,7 +21336,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_DEFENSE, + .argument = { .maxEffect = MAX_EFFECT_LOWER_DEFENSE }, .battleAnimScript = gBattleAnimMove_MaxPhantasm, }, @@ -21313,7 +21352,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_HAIL, + .argument = { .maxEffect = MAX_EFFECT_HAIL }, .battleAnimScript = gBattleAnimMove_MaxHailstorm, }, @@ -21329,7 +21368,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAISE_TEAM_SP_ATK, + .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SP_ATK }, .battleAnimScript = gBattleAnimMove_MaxOoze, }, @@ -21345,7 +21384,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAIN, + .argument = { .maxEffect = MAX_EFFECT_RAIN }, .battleAnimScript = gBattleAnimMove_MaxGeyser, }, @@ -21361,7 +21400,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAISE_TEAM_SPEED, + .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SPEED }, .battleAnimScript = gBattleAnimMove_MaxAirstream, }, @@ -21377,7 +21416,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_MISTY_TERRAIN, + .argument = { .maxEffect = MAX_EFFECT_MISTY_TERRAIN }, .battleAnimScript = gBattleAnimMove_MaxStarfall, }, @@ -21393,7 +21432,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_ATTACK, + .argument = { .maxEffect = MAX_EFFECT_LOWER_ATTACK }, .battleAnimScript = gBattleAnimMove_MaxWyrmwind, }, @@ -21409,7 +21448,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_PSYCHIC_TERRAIN, + .argument = { .maxEffect = MAX_EFFECT_PSYCHIC_TERRAIN }, .battleAnimScript = gBattleAnimMove_MaxMindstorm, }, @@ -21425,7 +21464,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_SANDSTORM, + .argument = { .maxEffect = MAX_EFFECT_SANDSTORM }, .battleAnimScript = gBattleAnimMove_MaxRockfall, }, @@ -21441,7 +21480,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAISE_TEAM_SP_DEF, + .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SP_DEF }, .skyBattleBanned = B_EXTRAPOLATED_MOVE_FLAGS, .battleAnimScript = gBattleAnimMove_MaxQuake, }, @@ -21458,7 +21497,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_SP_DEF, + .argument = { .maxEffect = MAX_EFFECT_LOWER_SP_DEF }, .battleAnimScript = gBattleAnimMove_MaxDarkness, }, @@ -21474,7 +21513,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_GRASSY_TERRAIN, + .argument = { .maxEffect = MAX_EFFECT_GRASSY_TERRAIN }, .battleAnimScript = gBattleAnimMove_MaxOvergrowth, }, @@ -21490,7 +21529,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RAISE_TEAM_DEFENSE, + .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_DEFENSE }, .battleAnimScript = gBattleAnimMove_MaxSteelspike, }, @@ -21506,7 +21545,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_VINE_LASH, + .argument = { .maxEffect = MAX_EFFECT_VINE_LASH }, .battleAnimScript = gBattleAnimMove_GMaxVineLash, }, @@ -21522,7 +21561,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_WILDFIRE, + .argument = { .maxEffect = MAX_EFFECT_WILDFIRE }, .battleAnimScript = gBattleAnimMove_GMaxWildfire, }, @@ -21538,7 +21577,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_CANNONADE, + .argument = { .maxEffect = MAX_EFFECT_CANNONADE }, .battleAnimScript = gBattleAnimMove_GMaxCannonade, }, @@ -21554,7 +21593,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_EFFECT_SPORE_FOES, + .argument = { .maxEffect = MAX_EFFECT_EFFECT_SPORE_FOES }, .battleAnimScript = gBattleAnimMove_GMaxBefuddle, }, @@ -21570,7 +21609,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_PARALYZE_FOES, + .argument = { .maxEffect = MAX_EFFECT_PARALYZE_FOES }, .battleAnimScript = gBattleAnimMove_GMaxVoltCrash, }, @@ -21586,7 +21625,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_CONFUSE_FOES_PAY_DAY, + .argument = { .maxEffect = MAX_EFFECT_CONFUSE_FOES_PAY_DAY }, .battleAnimScript = gBattleAnimMove_GMaxGoldRush, }, @@ -21602,7 +21641,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_CRIT_PLUS, + .argument = { .maxEffect = MAX_EFFECT_CRIT_PLUS }, .battleAnimScript = gBattleAnimMove_GMaxChiStrike, }, @@ -21618,7 +21657,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_MEAN_LOOK, + .argument = { .maxEffect = MAX_EFFECT_MEAN_LOOK }, .battleAnimScript = gBattleAnimMove_GMaxTerror, }, @@ -21634,7 +21673,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_SPEED_2_FOES, + .argument = { .maxEffect = MAX_EFFECT_LOWER_SPEED_2_FOES }, .battleAnimScript = gBattleAnimMove_GMaxFoamBurst, }, @@ -21650,7 +21689,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_AURORA_VEIL, + .argument = { .maxEffect = MAX_EFFECT_AURORA_VEIL }, .battleAnimScript = gBattleAnimMove_GMaxResonance, }, @@ -21666,7 +21705,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_INFATUATE_FOES, + .argument = { .maxEffect = MAX_EFFECT_INFATUATE_FOES }, .battleAnimScript = gBattleAnimMove_GMaxCuddle, }, @@ -21682,7 +21721,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_RECYCLE_BERRIES, + .argument = { .maxEffect = MAX_EFFECT_RECYCLE_BERRIES }, .battleAnimScript = gBattleAnimMove_GMaxReplenish, }, @@ -21698,7 +21737,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_POISON_FOES, + .argument = { .maxEffect = MAX_EFFECT_POISON_FOES }, .battleAnimScript = gBattleAnimMove_GMaxMalodor, }, @@ -21714,7 +21753,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_TORMENT_FOES, + .argument = { .maxEffect = MAX_EFFECT_TORMENT_FOES }, .battleAnimScript = gBattleAnimMove_GMaxMeltdown, }, @@ -21730,7 +21769,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_FIXED_POWER, + .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER }, .ignoresTargetAbility = TRUE, .battleAnimScript = gBattleAnimMove_GMaxDrumSolo, }, @@ -21747,7 +21786,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_FIXED_POWER, + .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER }, .ignoresTargetAbility = TRUE, .battleAnimScript = gBattleAnimMove_GMaxFireball, }, @@ -21764,7 +21803,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_FIXED_POWER, + .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER }, .ignoresTargetAbility = TRUE, .battleAnimScript = gBattleAnimMove_GMaxHydrosnipe, }, @@ -21781,7 +21820,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_DEFOG, + .argument = { .maxEffect = MAX_EFFECT_DEFOG }, .battleAnimScript = gBattleAnimMove_GMaxWindRage, }, @@ -21797,7 +21836,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_GRAVITY, + .argument = { .maxEffect = MAX_EFFECT_GRAVITY }, .battleAnimScript = gBattleAnimMove_GMaxGravitas, }, @@ -21813,7 +21852,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_STEALTH_ROCK, + .argument = { .maxEffect = MAX_EFFECT_STEALTH_ROCK }, .battleAnimScript = gBattleAnimMove_GMaxStonesurge, }, @@ -21829,7 +21868,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_VOLCALITH, + .argument = { .maxEffect = MAX_EFFECT_VOLCALITH }, .battleAnimScript = gBattleAnimMove_GMaxVolcalith, }, @@ -21845,7 +21884,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_LOWER_EVASIVENESS_FOES, + .argument = { .maxEffect = MAX_EFFECT_LOWER_EVASIVENESS_FOES }, .battleAnimScript = gBattleAnimMove_GMaxTartness, }, @@ -21861,7 +21900,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_AROMATHERAPY, + .argument = { .maxEffect = MAX_EFFECT_AROMATHERAPY }, .battleAnimScript = gBattleAnimMove_GMaxSweetness, }, @@ -21877,7 +21916,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_SANDBLAST_FOES, + .argument = { .maxEffect = MAX_EFFECT_SANDBLAST_FOES }, .battleAnimScript = gBattleAnimMove_GMaxSandblast, }, @@ -21893,7 +21932,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_POISON_PARALYZE_FOES, + .argument = { .maxEffect = MAX_EFFECT_POISON_PARALYZE_FOES }, .battleAnimScript = gBattleAnimMove_GMaxStunShock, }, @@ -21909,7 +21948,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_FIRE_SPIN_FOES, + .argument = { .maxEffect = MAX_EFFECT_FIRE_SPIN_FOES }, .battleAnimScript = gBattleAnimMove_GMaxCentiferno, }, @@ -21925,7 +21964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_CONFUSE_FOES, + .argument = { .maxEffect = MAX_EFFECT_CONFUSE_FOES }, .battleAnimScript = gBattleAnimMove_GMaxSmite, }, @@ -21942,7 +21981,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_YAWN_FOE, + .argument = { .maxEffect = MAX_EFFECT_YAWN_FOE }, .battleAnimScript = gBattleAnimMove_GMaxSnooze, }, @@ -21958,7 +21997,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_HEAL_TEAM, + .argument = { .maxEffect = MAX_EFFECT_HEAL_TEAM }, .battleAnimScript = gBattleAnimMove_GMaxFinale, }, @@ -21974,7 +22013,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_STEELSURGE, + .argument = { .maxEffect = MAX_EFFECT_STEELSURGE }, .battleAnimScript = gBattleAnimMove_GMaxSteelsurge, }, @@ -21990,7 +22029,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_SPITE, + .argument = { .maxEffect = MAX_EFFECT_SPITE }, .battleAnimScript = gBattleAnimMove_GMaxDepletion, }, @@ -22006,7 +22045,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_BYPASS_PROTECT, + .argument = { .maxEffect = MAX_EFFECT_BYPASS_PROTECT }, .battleAnimScript = gBattleAnimMove_GMaxOneBlow, }, @@ -22022,7 +22061,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, - .argument = MAX_EFFECT_BYPASS_PROTECT, + .argument = { .maxEffect = MAX_EFFECT_BYPASS_PROTECT }, .battleAnimScript = gBattleAnimMove_GMaxRapidFlow, }, diff --git a/src/data/object_events/object_event_graphics.h b/src/data/object_events/object_event_graphics.h index 2d0da76d2d..23c13d61e5 100644 --- a/src/data/object_events/object_event_graphics.h +++ b/src/data/object_events/object_event_graphics.h @@ -460,3 +460,6 @@ const u16 gObjectEventPal_BeastBall[] = INCBIN_U16("graphics/object_events/pics/ const u16 gObjectEventPal_StrangeBall[] = INCBIN_U16("graphics/object_events/pics/misc/ball_strange.gbapal"); #endif //ITEM_STRANGE_BALL #endif //OW_FOLLOWERS_POKEBALLS + +const u32 gFieldEffectObjectPic_CaveDust[] = INCBIN_U32("graphics/field_effects/pics/cave_dust.4bpp"); +const u16 gFieldEffectObjectPalette_CaveDust[] = INCBIN_U16("graphics/field_effects/palettes/cave_dust.gbapal"); diff --git a/src/data/party_menu.h b/src/data/party_menu.h index 3bc86593fa..e6cb13ee6d 100644 --- a/src/data/party_menu.h +++ b/src/data/party_menu.h @@ -838,7 +838,7 @@ static const u8 *const sUnionRoomTradeMessages[] = }; static const u32 sHeldItemGfx[] = INCBIN_U32("graphics/party_menu/hold_icons.4bpp"); -static const u16 sHeldItemPalette[] = INCBIN_U16("graphics/party_menu/hold_icons.gbapal"); +const u16 gHeldItemPalette[] = INCBIN_U16("graphics/party_menu/hold_icons.gbapal"); static const struct OamData sOamData_HeldItem = { @@ -875,14 +875,14 @@ static const union AnimCmd *const sSpriteAnimTable_HeldItem[] = sSpriteAnim_HeldMail, }; -static const struct SpriteSheet sSpriteSheet_HeldItem = +const struct SpriteSheet gSpriteSheet_HeldItem = { .data = sHeldItemGfx, .size = sizeof(sHeldItemGfx), .tag = TAG_HELD_ITEM }; static const struct SpritePalette sSpritePalette_HeldItem = { - .data = sHeldItemPalette, .tag = TAG_HELD_ITEM + .data = gHeldItemPalette, .tag = TAG_HELD_ITEM }; static const struct SpriteTemplate sSpriteTemplate_HeldItem = diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index ba9f845395..314b5bd73f 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -2533,7 +2533,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .frontPicSize = MON_COORDS_SIZE(32, 40), .frontPicYOffset = 13, .frontAnimFrames = sAnims_PichuSpikyEared, - //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + .frontAnimId = ANIM_V_JUMPS_H_JUMPS, .backPic = gMonBackPic_PichuSpikyEared, .backPicSize = MON_COORDS_SIZE(48, 56), .backPicYOffset = 8, @@ -2544,11 +2544,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .iconPalIndex = 1, SHADOW(2, 0, SHADOW_SIZE_S) FOOTPRINT(Pichu) - OVERWORLD( + OVERWORLD_SET_ANIM( sPicTable_PichuSpikyEared, SIZE_32x32, SHADOW_SIZE_M, TRACKS_FOOT, + sAnimTable_Following_Asym, gOverworldPalette_PichuSpikyEared, gShinyOverworldPalette_PichuSpikyEared ) diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h index 56ec319a57..adf64468aa 100644 --- a/src/data/pokemon_graphics/front_pic_anims.h +++ b/src/data/pokemon_graphics/front_pic_anims.h @@ -340,7 +340,17 @@ static const union AnimCmd sAnim_Pichu_1[] = ANIMCMD_END, }; -PLACEHOLDER_ANIM_SINGLE_FRAME(PichuSpikyEared); +static const union AnimCmd sAnim_PichuSpikyEared_1[] = +{ + ANIMCMD_FRAME(0, 10), + ANIMCMD_FRAME(1, 10), + ANIMCMD_FRAME(0, 10), + ANIMCMD_FRAME(1, 10), + ANIMCMD_FRAME(0, 10), + ANIMCMD_FRAME(1, 10), + ANIMCMD_FRAME(0, 1), + ANIMCMD_END, +}; #endif //P_GEN_2_CROSS_EVOS static const union AnimCmd sAnim_Pikachu_1[] = diff --git a/src/data/trainers.h b/src/data/trainers.h index ebc85e9cab..f8e0952716 100644 --- a/src/data/trainers.h +++ b/src/data/trainers.h @@ -15,7 +15,7 @@ .trainerClass = TRAINER_CLASS_PKMN_TRAINER_1, #line 79 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 81 TRAINER_ENCOUNTER_MUSIC_MALE, #line 82 @@ -34,7 +34,7 @@ .trainerClass = TRAINER_CLASS_HIKER, #line 87 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 89 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 90 @@ -66,7 +66,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 100 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 102 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 103 @@ -98,7 +98,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 113 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 115 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 116 @@ -141,7 +141,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 130 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 132 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 133 @@ -173,7 +173,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 143 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 145 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 146 @@ -205,7 +205,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 156 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 158 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 159 @@ -237,7 +237,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 169 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 171 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 172 @@ -269,7 +269,7 @@ .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 182 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 184 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 185 @@ -301,9 +301,9 @@ .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 195 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 196 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 197 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 198 @@ -390,7 +390,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 228 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 230 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 231 @@ -422,7 +422,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 241 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 243 TRAINER_ENCOUNTER_MUSIC_COOL, #line 244 @@ -467,7 +467,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 259 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 261 TRAINER_ENCOUNTER_MUSIC_COOL, #line 262 @@ -510,7 +510,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 276 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 278 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 279 @@ -553,9 +553,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 293 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 294 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 295 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 296 @@ -587,7 +587,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 306 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 308 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 309 @@ -619,7 +619,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 319 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 321 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 322 @@ -651,7 +651,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 332 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 334 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 335 @@ -694,7 +694,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 349 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 351 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 352 @@ -737,7 +737,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 366 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 368 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 369 @@ -791,7 +791,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 387 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 389 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 390 @@ -823,7 +823,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 400 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 402 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 403 @@ -866,7 +866,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 417 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 419 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 420 @@ -898,7 +898,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 430 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 432 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 433 @@ -930,7 +930,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 443 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 445 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 446 @@ -962,7 +962,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 456 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 458 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 459 @@ -1005,9 +1005,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 473 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 474 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 475 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 476 @@ -1039,9 +1039,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 486 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 487 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 488 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 489 @@ -1073,9 +1073,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 499 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 500 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 501 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 502 @@ -1107,7 +1107,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 512 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 514 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 515 @@ -1150,7 +1150,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AQUA_ADMIN, #line 529 .trainerPic = TRAINER_PIC_AQUA_ADMIN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 531 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 532 @@ -1195,7 +1195,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 547 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 549 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 550 @@ -1227,9 +1227,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AQUA_ADMIN, #line 560 .trainerPic = TRAINER_PIC_AQUA_ADMIN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 561 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 562 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 563 @@ -1272,9 +1272,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AQUA_ADMIN, #line 577 .trainerPic = TRAINER_PIC_AQUA_ADMIN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 578 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 579 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 580 @@ -1317,7 +1317,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AQUA_LEADER, #line 594 .trainerPic = TRAINER_PIC_AQUA_LEADER_ARCHIE, - .encounterMusic_gender = + .encounterMusic_gender = #line 596 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 597 @@ -1373,9 +1373,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 616 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 617 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 618 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 619 @@ -1407,9 +1407,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 629 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 630 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 631 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 632 @@ -1452,9 +1452,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 646 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 647 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 648 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 649 @@ -1508,7 +1508,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 667 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 669 TRAINER_ENCOUNTER_MUSIC_COOL, #line 670 @@ -1562,9 +1562,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 688 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 689 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 690 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 691 @@ -1607,9 +1607,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 705 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 706 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 707 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 708 @@ -1652,9 +1652,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 722 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 723 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 724 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 725 @@ -1708,9 +1708,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 743 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 744 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 745 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 746 @@ -1764,9 +1764,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 764 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 765 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 766 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 767 @@ -1820,7 +1820,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 785 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 787 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 788 @@ -1859,7 +1859,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 802 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 804 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 805 @@ -1934,7 +1934,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 835 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 837 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 838 @@ -1991,7 +1991,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 860 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 862 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 863 @@ -2030,7 +2030,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 877 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 879 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 880 @@ -2069,7 +2069,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 894 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 896 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 897 @@ -2108,7 +2108,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 911 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 913 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 914 @@ -2147,7 +2147,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 928 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 930 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 931 @@ -2190,7 +2190,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 945 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 947 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 948 @@ -2233,7 +2233,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 962 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 964 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 965 @@ -2276,7 +2276,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 979 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 981 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 982 @@ -2319,7 +2319,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 996 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 998 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 999 @@ -2362,7 +2362,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_INTERVIEWER, #line 1013 .trainerPic = TRAINER_PIC_INTERVIEWER, - .encounterMusic_gender = + .encounterMusic_gender = #line 1015 TRAINER_ENCOUNTER_MUSIC_INTERVIEWER, #line 1016 @@ -2419,9 +2419,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1038 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1039 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1040 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1041 @@ -2464,9 +2464,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1055 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1056 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1057 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1058 @@ -2498,9 +2498,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1068 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1069 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1070 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1071 @@ -2532,9 +2532,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1081 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1082 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1083 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1084 @@ -2577,9 +2577,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1098 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1099 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1100 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1101 @@ -2622,9 +2622,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1115 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1116 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1117 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1118 @@ -2667,9 +2667,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 1132 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1133 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1134 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1135 @@ -2712,7 +2712,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1149 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1151 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1152 @@ -2751,7 +2751,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1166 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1168 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1169 @@ -2794,7 +2794,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1183 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1185 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1186 @@ -2826,7 +2826,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1196 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1198 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1199 @@ -2865,7 +2865,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1213 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1215 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1216 @@ -2904,7 +2904,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1230 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1232 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1233 @@ -2943,7 +2943,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 1247 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1249 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 1250 @@ -2982,7 +2982,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1264 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1266 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1267 @@ -3022,7 +3022,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1281 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1283 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1284 @@ -3062,7 +3062,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1298 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1300 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1301 @@ -3104,7 +3104,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1315 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1317 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1318 @@ -3143,7 +3143,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1331 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1333 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1334 @@ -3256,7 +3256,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1381 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1383 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1384 @@ -3312,7 +3312,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1403 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1405 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1406 @@ -3357,7 +3357,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1421 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1423 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1424 @@ -3413,7 +3413,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1443 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1445 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1446 @@ -3458,7 +3458,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1461 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1463 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1464 @@ -3503,7 +3503,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1479 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1481 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1482 @@ -3559,7 +3559,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1501 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1503 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1504 @@ -3626,7 +3626,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1527 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1529 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1530 @@ -3682,7 +3682,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1549 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1551 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1552 @@ -3738,7 +3738,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1571 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1573 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1574 @@ -3794,7 +3794,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1593 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1595 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1596 @@ -3850,7 +3850,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1615 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1617 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1618 @@ -3906,7 +3906,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1637 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 1639 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1640 @@ -3951,9 +3951,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1655 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1656 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1657 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1658 @@ -3992,9 +3992,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1671 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1672 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1673 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1674 @@ -4034,9 +4034,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1688 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1689 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1690 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1691 @@ -4075,9 +4075,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1704 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1705 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1706 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1707 @@ -4154,9 +4154,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1738 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1739 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1740 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1741 @@ -4201,9 +4201,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1756 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1757 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1758 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1759 @@ -4259,9 +4259,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1778 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1779 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1780 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1781 @@ -4295,9 +4295,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1792 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1793 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1794 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1795 @@ -4331,9 +4331,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1806 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1807 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1808 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1809 @@ -4367,9 +4367,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1820 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1821 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1822 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1823 @@ -4425,9 +4425,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1842 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1843 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1844 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1845 @@ -4472,9 +4472,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1860 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1861 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1862 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1863 @@ -4530,9 +4530,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1882 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1883 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1884 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1885 @@ -4588,9 +4588,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1904 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1905 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1906 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1907 @@ -4646,9 +4646,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1926 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1927 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1928 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1929 @@ -4704,9 +4704,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 1948 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 1949 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1950 TRAINER_ENCOUNTER_MUSIC_COOL, #line 1951 @@ -4762,9 +4762,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 1970 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 1971 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1972 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 1973 @@ -4807,9 +4807,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 1987 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 1988 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 1989 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 1990 @@ -4852,9 +4852,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2004 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2005 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2006 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2007 @@ -4897,9 +4897,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2021 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2022 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2023 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2024 @@ -4931,9 +4931,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2034 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2035 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2036 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2037 @@ -4965,9 +4965,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2047 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2048 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2049 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2050 @@ -5010,9 +5010,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2064 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2065 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2066 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2067 @@ -5055,9 +5055,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2081 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2082 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2083 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2084 @@ -5100,9 +5100,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 2098 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2099 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2100 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2101 @@ -5156,9 +5156,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2119 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2120 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2121 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2122 @@ -5194,9 +5194,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2133 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2134 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2135 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2136 @@ -5259,7 +5259,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 2159 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2161 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 2162 @@ -5313,9 +5313,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2180 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2181 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2182 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2183 @@ -5356,9 +5356,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2196 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2197 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2198 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2199 @@ -5394,9 +5394,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2210 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2211 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2212 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2213 @@ -5432,9 +5432,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2224 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2225 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2226 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2227 @@ -5470,9 +5470,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2238 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2239 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2240 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2241 @@ -5508,9 +5508,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2252 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2253 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2254 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2255 @@ -5546,9 +5546,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 2266 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2267 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2268 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2269 @@ -5591,9 +5591,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2284 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2285 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2286 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2287 @@ -5625,9 +5625,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2297 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2298 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2299 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2300 @@ -5659,9 +5659,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2310 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2311 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2312 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2313 @@ -5693,9 +5693,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2323 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2324 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2325 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2326 @@ -5752,9 +5752,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2348 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2349 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2350 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2351 @@ -5786,9 +5786,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2361 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2362 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2363 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2364 @@ -5820,9 +5820,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2374 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2375 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2376 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2377 @@ -5896,9 +5896,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2406 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2407 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2408 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2409 @@ -5941,9 +5941,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2423 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2424 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2425 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2426 @@ -6000,9 +6000,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2448 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2449 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2450 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2451 @@ -6059,9 +6059,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2473 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2474 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2475 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2476 @@ -6118,9 +6118,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2498 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2499 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2500 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2501 @@ -6177,7 +6177,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2523 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2525 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2526 @@ -6213,9 +6213,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 2537 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 2538 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2539 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 2540 @@ -6258,7 +6258,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2554 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2556 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2557 @@ -6294,7 +6294,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2568 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2570 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2571 @@ -6330,7 +6330,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2582 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2584 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2585 @@ -6366,7 +6366,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2596 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2598 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2599 @@ -6402,7 +6402,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 2610 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2612 TRAINER_ENCOUNTER_MUSIC_RICH, #line 2613 @@ -6445,7 +6445,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2628 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2630 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2631 @@ -6477,9 +6477,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 2641 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 2642 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2643 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 2644 @@ -6522,7 +6522,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2658 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2660 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2661 @@ -6554,9 +6554,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 2671 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 2672 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 2673 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 2674 @@ -6588,7 +6588,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2684 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2686 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2687 @@ -6620,7 +6620,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2697 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2699 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2700 @@ -6663,7 +6663,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2714 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2716 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2717 @@ -6706,7 +6706,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 2731 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 2733 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 2734 @@ -6749,7 +6749,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2748 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2750 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2751 @@ -6781,7 +6781,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2761 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2763 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2764 @@ -6813,7 +6813,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2774 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2776 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2777 @@ -6856,7 +6856,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2791 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2793 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2794 @@ -6910,7 +6910,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2812 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2814 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2815 @@ -6942,7 +6942,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2825 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2827 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2828 @@ -6974,7 +6974,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2838 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2840 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2841 @@ -7006,7 +7006,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2851 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2853 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2854 @@ -7049,7 +7049,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2868 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2870 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2871 @@ -7092,7 +7092,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2885 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2887 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2888 @@ -7124,7 +7124,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2898 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2900 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2901 @@ -7156,7 +7156,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2911 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2913 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2914 @@ -7188,7 +7188,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2924 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2926 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2927 @@ -7220,7 +7220,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2937 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2939 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2940 @@ -7274,7 +7274,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2958 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2960 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2961 @@ -7306,7 +7306,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2971 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2973 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2974 @@ -7338,7 +7338,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 2984 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 2986 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 2987 @@ -7381,7 +7381,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3001 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3003 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3004 @@ -7424,7 +7424,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3018 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3020 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3021 @@ -7456,7 +7456,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3031 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3033 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3034 @@ -7488,7 +7488,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3044 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3046 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3047 @@ -7520,7 +7520,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3057 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3059 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3060 @@ -7552,7 +7552,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3070 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3072 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3073 @@ -7606,7 +7606,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3091 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3093 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3094 @@ -7649,7 +7649,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3108 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3110 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3111 @@ -7681,7 +7681,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3121 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3123 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3124 @@ -7713,7 +7713,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3134 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3136 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3137 @@ -7756,7 +7756,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 3151 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3153 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 3154 @@ -7799,7 +7799,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3168 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3170 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3171 @@ -7831,7 +7831,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3181 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3183 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3184 @@ -7874,7 +7874,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3198 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3200 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3201 @@ -7906,7 +7906,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3211 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3213 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3214 @@ -7949,7 +7949,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3228 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3230 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3231 @@ -7981,7 +7981,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3241 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3243 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3244 @@ -8013,7 +8013,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3254 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3256 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3257 @@ -8056,7 +8056,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3271 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3273 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3274 @@ -8110,7 +8110,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3292 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3294 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3295 @@ -8177,7 +8177,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3317 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3319 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3320 @@ -8220,7 +8220,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3334 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3336 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3337 @@ -8252,7 +8252,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 3347 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 3349 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3350 @@ -8284,7 +8284,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3360 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3362 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3363 @@ -8340,9 +8340,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 3384 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 3385 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 3386 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 3387 @@ -8385,7 +8385,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 3401 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 3403 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 3404 @@ -8417,7 +8417,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3414 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3416 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3417 @@ -8460,7 +8460,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3431 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3433 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3434 @@ -8503,7 +8503,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3448 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3450 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3451 @@ -8546,7 +8546,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3465 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3467 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3468 @@ -8600,7 +8600,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3486 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3488 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3489 @@ -8654,7 +8654,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3507 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3509 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3510 @@ -8708,7 +8708,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 3528 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 3530 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 3531 @@ -8762,7 +8762,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3549 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3551 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3552 @@ -8794,7 +8794,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3562 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3564 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3565 @@ -8837,7 +8837,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3579 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3581 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3582 @@ -8869,7 +8869,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3592 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3594 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3595 @@ -8901,7 +8901,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3605 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3607 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3608 @@ -8933,7 +8933,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3618 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3620 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3621 @@ -8976,7 +8976,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3635 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3637 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3638 @@ -9019,7 +9019,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3652 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3654 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3655 @@ -9062,7 +9062,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3669 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3671 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3672 @@ -9105,7 +9105,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 3686 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3688 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 3689 @@ -9148,7 +9148,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3703 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3705 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3706 @@ -9187,7 +9187,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3720 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3722 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3723 @@ -9262,7 +9262,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3753 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3755 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3756 @@ -9294,7 +9294,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3766 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3768 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3769 @@ -9337,7 +9337,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3783 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3785 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3786 @@ -9369,7 +9369,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3796 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3798 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3799 @@ -9412,9 +9412,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 3813 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3814 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 3815 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 3816 @@ -9446,7 +9446,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3826 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3828 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3829 @@ -9478,7 +9478,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3839 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3841 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3842 @@ -9521,7 +9521,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3856 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3858 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3859 @@ -9564,7 +9564,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3873 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3875 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3876 @@ -9618,7 +9618,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 3894 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 3896 TRAINER_ENCOUNTER_MUSIC_MALE, #line 3897 @@ -9672,7 +9672,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 3915 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 3917 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 3918 @@ -9704,7 +9704,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 3928 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 3930 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 3931 @@ -9758,7 +9758,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 3949 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 3951 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 3952 @@ -9812,7 +9812,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 3970 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 3972 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 3973 @@ -9866,7 +9866,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 3991 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 3993 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 3994 @@ -9909,7 +9909,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 4008 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 4010 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 4011 @@ -9963,7 +9963,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 4029 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 4031 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 4032 @@ -10017,7 +10017,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 4050 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 4052 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 4053 @@ -10082,7 +10082,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 4075 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 4077 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 4078 @@ -10160,7 +10160,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4104 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4106 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4107 @@ -10196,7 +10196,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4118 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4120 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4121 @@ -10228,7 +10228,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4131 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4133 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4134 @@ -10260,7 +10260,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4144 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4146 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4147 @@ -10292,7 +10292,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4157 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4159 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4160 @@ -10346,7 +10346,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4178 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4180 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4181 @@ -10389,7 +10389,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4195 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4197 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4198 @@ -10421,7 +10421,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4208 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4210 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4211 @@ -10464,7 +10464,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4225 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4227 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4228 @@ -10507,7 +10507,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4242 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4244 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4245 @@ -10550,7 +10550,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4259 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 4261 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4262 @@ -10593,9 +10593,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4276 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4277 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4278 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4279 @@ -10631,9 +10631,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4290 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4291 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4292 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4293 @@ -10665,9 +10665,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4303 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4304 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4305 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4306 @@ -10699,9 +10699,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4316 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4317 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4318 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4319 @@ -10733,9 +10733,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4329 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4330 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4331 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4332 @@ -10789,9 +10789,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4350 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4351 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4352 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4353 @@ -10834,9 +10834,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4367 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4368 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4369 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4370 @@ -10879,9 +10879,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4384 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4385 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4386 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4387 @@ -10924,9 +10924,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4401 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4402 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4403 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4404 @@ -10969,9 +10969,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4418 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4419 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4420 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4421 @@ -11014,9 +11014,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 4435 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 4436 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4437 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 4438 @@ -11059,7 +11059,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4452 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4454 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4455 @@ -11091,7 +11091,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4465 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4467 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4468 @@ -11134,7 +11134,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4482 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4484 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4485 @@ -11166,7 +11166,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4495 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4497 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4498 @@ -11198,7 +11198,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4508 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4510 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4511 @@ -11255,7 +11255,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4533 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4535 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4536 @@ -11311,7 +11311,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 4557 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4559 TRAINER_ENCOUNTER_MUSIC_RICH, #line 4560 @@ -11386,7 +11386,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_ELITE_FOUR, #line 4590 .trainerPic = TRAINER_PIC_ELITE_FOUR_SIDNEY, - .encounterMusic_gender = + .encounterMusic_gender = #line 4592 TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR, #line 4593 @@ -11396,7 +11396,6 @@ F_TRAINER_FEMALE | #line 4595 .aiFlags = AI_FLAG_BASIC_TRAINER | AI_FLAG_FORCE_SETUP_FIRST_TURN, #line 4596 - .mugshotEnabled = TRUE, .mugshotColor = MUGSHOT_COLOR_PURPLE, .partySize = 5, .party = (const struct TrainerMon[]) @@ -11504,9 +11503,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_ELITE_FOUR, #line 4641 .trainerPic = TRAINER_PIC_ELITE_FOUR_PHOEBE, - .encounterMusic_gender = + .encounterMusic_gender = #line 4642 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4643 TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR, #line 4644 @@ -11516,7 +11515,6 @@ F_TRAINER_FEMALE | #line 4646 .aiFlags = AI_FLAG_BASIC_TRAINER, #line 4647 - .mugshotEnabled = TRUE, .mugshotColor = MUGSHOT_COLOR_GREEN, .partySize = 5, .party = (const struct TrainerMon[]) @@ -11624,9 +11622,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_ELITE_FOUR, #line 4692 .trainerPic = TRAINER_PIC_ELITE_FOUR_GLACIA, - .encounterMusic_gender = + .encounterMusic_gender = #line 4693 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4694 TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR, #line 4695 @@ -11636,7 +11634,6 @@ F_TRAINER_FEMALE | #line 4697 .aiFlags = AI_FLAG_BASIC_TRAINER, #line 4698 - .mugshotEnabled = TRUE, .mugshotColor = MUGSHOT_COLOR_PINK, .partySize = 5, .party = (const struct TrainerMon[]) @@ -11744,7 +11741,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_ELITE_FOUR, #line 4743 .trainerPic = TRAINER_PIC_ELITE_FOUR_DRAKE, - .encounterMusic_gender = + .encounterMusic_gender = #line 4745 TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR, #line 4746 @@ -11754,7 +11751,6 @@ F_TRAINER_FEMALE | #line 4748 .aiFlags = AI_FLAG_BASIC_TRAINER, #line 4749 - .mugshotEnabled = TRUE, .mugshotColor = MUGSHOT_COLOR_BLUE, .partySize = 5, .party = (const struct TrainerMon[]) @@ -11862,9 +11858,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4794 .trainerPic = TRAINER_PIC_LEADER_ROXANNE, - .encounterMusic_gender = + .encounterMusic_gender = #line 4795 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4796 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 4797 @@ -11943,7 +11939,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4828 .trainerPic = TRAINER_PIC_LEADER_BRAWLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 4830 TRAINER_ENCOUNTER_MUSIC_MALE, #line 4831 @@ -12022,7 +12018,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4862 .trainerPic = TRAINER_PIC_LEADER_WATTSON, - .encounterMusic_gender = + .encounterMusic_gender = #line 4864 TRAINER_ENCOUNTER_MUSIC_MALE, #line 4865 @@ -12119,9 +12115,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4904 .trainerPic = TRAINER_PIC_LEADER_FLANNERY, - .encounterMusic_gender = + .encounterMusic_gender = #line 4905 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4906 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 4907 @@ -12218,7 +12214,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4946 .trainerPic = TRAINER_PIC_LEADER_NORMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 4948 TRAINER_ENCOUNTER_MUSIC_MALE, #line 4949 @@ -12315,9 +12311,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 4988 .trainerPic = TRAINER_PIC_LEADER_WINONA, - .encounterMusic_gender = + .encounterMusic_gender = #line 4989 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 4990 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 4991 @@ -12432,7 +12428,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 5038 .trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA, - .encounterMusic_gender = + .encounterMusic_gender = #line 5040 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 5041 @@ -12531,7 +12527,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 5080 .trainerPic = TRAINER_PIC_LEADER_JUAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 5082 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5083 @@ -12646,7 +12642,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5130 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5132 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5133 @@ -12678,7 +12674,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5143 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5145 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5146 @@ -12710,7 +12706,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5156 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5158 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5159 @@ -12764,7 +12760,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5177 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5179 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5180 @@ -12807,7 +12803,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5194 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5196 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5197 @@ -12850,7 +12846,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5211 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5213 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5214 @@ -12893,7 +12889,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5228 .trainerPic = TRAINER_PIC_SCHOOL_KID_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5230 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5231 @@ -12947,9 +12943,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5249 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5250 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5251 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5252 @@ -12981,9 +12977,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5262 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5263 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5264 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5265 @@ -13026,9 +13022,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5279 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5280 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5281 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5282 @@ -13071,9 +13067,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5296 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5297 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5298 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5299 @@ -13116,9 +13112,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5313 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5314 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5315 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5316 @@ -13161,9 +13157,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SCHOOL_KID, #line 5330 .trainerPic = TRAINER_PIC_SCHOOL_KID_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5331 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5332 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 5333 @@ -13206,7 +13202,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5347 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5349 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5350 @@ -13263,7 +13259,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5372 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5374 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5375 @@ -13319,7 +13315,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5396 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5398 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5399 @@ -13375,7 +13371,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5420 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5422 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5423 @@ -13431,7 +13427,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5444 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5446 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5447 @@ -13487,7 +13483,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 5468 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 5470 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5471 @@ -13543,7 +13539,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_WINSTRATE, #line 5492 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5494 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5495 @@ -13590,7 +13586,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5509 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5511 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5512 @@ -13624,7 +13620,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5522 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5524 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5525 @@ -13765,7 +13761,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5579 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5581 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5582 @@ -13799,7 +13795,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5592 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5594 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5595 @@ -13833,7 +13829,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5605 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5607 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5608 @@ -13867,7 +13863,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5618 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5620 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5621 @@ -13901,9 +13897,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_WINSTRATE, #line 5631 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5632 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5633 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5634 @@ -13937,9 +13933,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5644 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5645 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5646 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5647 @@ -13973,9 +13969,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5657 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5658 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5659 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5660 @@ -14035,9 +14031,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5678 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5679 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5680 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5681 @@ -14084,9 +14080,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5695 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5696 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5697 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5698 @@ -14133,9 +14129,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5712 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5713 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5714 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5715 @@ -14182,9 +14178,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5729 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5730 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5731 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5732 @@ -14231,9 +14227,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 5746 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5747 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5748 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 5749 @@ -14280,7 +14276,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5763 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5765 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5766 @@ -14312,7 +14308,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5776 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5778 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5779 @@ -14351,7 +14347,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5793 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5795 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5796 @@ -14390,7 +14386,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5810 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5812 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5813 @@ -14429,7 +14425,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5827 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 5829 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5830 @@ -14468,9 +14464,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_WINSTRATE, #line 5844 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5845 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5846 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5847 @@ -14509,9 +14505,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5861 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5862 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5863 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5864 @@ -14554,9 +14550,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5878 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5879 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5880 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5881 @@ -14599,9 +14595,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5895 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5896 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5897 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5898 @@ -14644,9 +14640,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5912 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5913 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5914 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5915 @@ -14689,9 +14685,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 5929 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 5930 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 5931 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 5932 @@ -14734,7 +14730,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 5946 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 5948 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5949 @@ -14766,7 +14762,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 5959 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 5961 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5962 @@ -14809,7 +14805,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 5976 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 5978 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5979 @@ -14845,7 +14841,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 5990 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 5992 TRAINER_ENCOUNTER_MUSIC_MALE, #line 5993 @@ -14888,7 +14884,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6007 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6009 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6010 @@ -14920,7 +14916,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6020 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6022 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6023 @@ -14977,7 +14973,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 6045 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6047 TRAINER_ENCOUNTER_MUSIC_COOL, #line 6048 @@ -15036,9 +15032,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 6071 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6072 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6073 TRAINER_ENCOUNTER_MUSIC_COOL, #line 6074 @@ -15097,7 +15093,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6097 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6099 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6100 @@ -15129,7 +15125,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6110 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6112 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6113 @@ -15161,7 +15157,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6123 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6125 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6126 @@ -15193,7 +15189,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6136 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6138 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6139 @@ -15236,7 +15232,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6153 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6155 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6156 @@ -15290,7 +15286,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6174 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6176 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6177 @@ -15344,7 +15340,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6195 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6197 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6198 @@ -15387,7 +15383,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6212 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6214 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6215 @@ -15430,7 +15426,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6229 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6231 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6232 @@ -15473,7 +15469,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CHAMPION, #line 6246 .trainerPic = TRAINER_PIC_CHAMPION_WALLACE, - .encounterMusic_gender = + .encounterMusic_gender = #line 6248 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6249 @@ -15483,7 +15479,6 @@ F_TRAINER_FEMALE | #line 6251 .aiFlags = AI_FLAG_BASIC_TRAINER, #line 6252 - .mugshotEnabled = TRUE, .mugshotColor = MUGSHOT_COLOR_YELLOW, .partySize = 6, .party = (const struct TrainerMon[]) @@ -15609,7 +15604,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6305 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6307 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6308 @@ -15663,7 +15658,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6326 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6328 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6329 @@ -15717,7 +15712,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6347 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6349 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6350 @@ -15771,7 +15766,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6368 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6370 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6371 @@ -15825,7 +15820,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6389 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6391 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6392 @@ -15857,7 +15852,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6402 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6404 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6405 @@ -15922,7 +15917,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6427 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6429 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6430 @@ -15954,7 +15949,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6440 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6442 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6443 @@ -15997,7 +15992,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6457 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6459 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6460 @@ -16029,7 +16024,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6470 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6472 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6473 @@ -16072,7 +16067,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6487 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6489 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6490 @@ -16126,7 +16121,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6508 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6510 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6511 @@ -16191,7 +16186,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6533 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6535 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6536 @@ -16256,7 +16251,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6558 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6560 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6561 @@ -16321,7 +16316,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 6583 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 6585 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 6586 @@ -16408,7 +16403,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6616 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6618 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6619 @@ -16462,7 +16457,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6637 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6639 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6640 @@ -16505,7 +16500,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6654 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6656 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6657 @@ -16537,7 +16532,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6667 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6669 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6670 @@ -16569,7 +16564,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6680 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6682 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6683 @@ -16601,7 +16596,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6693 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6695 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6696 @@ -16633,7 +16628,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6706 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6708 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6709 @@ -16665,9 +16660,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6719 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6720 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6721 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6722 @@ -16699,9 +16694,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6732 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6733 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6734 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6735 @@ -16755,9 +16750,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6753 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6754 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6755 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6756 @@ -16789,9 +16784,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6766 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6767 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6768 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6769 @@ -16823,9 +16818,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6779 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6780 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6781 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6782 @@ -16857,9 +16852,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6792 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6793 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6794 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6795 @@ -16891,7 +16886,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6805 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6807 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6808 @@ -16923,7 +16918,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6818 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6820 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6821 @@ -16955,7 +16950,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6831 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6833 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6834 @@ -16987,7 +16982,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6844 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6846 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6847 @@ -17019,7 +17014,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6857 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6859 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6860 @@ -17051,9 +17046,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6870 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6871 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6872 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6873 @@ -17085,9 +17080,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6883 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6884 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6885 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6886 @@ -17119,9 +17114,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6896 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6897 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6898 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6899 @@ -17153,9 +17148,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6909 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6910 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6911 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6912 @@ -17187,9 +17182,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6922 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 6923 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 6924 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 6925 @@ -17221,7 +17216,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6935 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6937 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 6938 @@ -17264,7 +17259,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 6952 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 6954 TRAINER_ENCOUNTER_MUSIC_MALE, #line 6955 @@ -17307,7 +17302,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6969 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6971 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 6972 @@ -17339,7 +17334,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6982 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 6984 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 6985 @@ -17382,7 +17377,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 6999 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 7001 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7002 @@ -17425,7 +17420,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7016 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 7018 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7019 @@ -17457,7 +17452,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7029 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 7031 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7032 @@ -17489,7 +17484,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7042 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 7044 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7045 @@ -17521,7 +17516,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7055 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 7057 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7058 @@ -17553,9 +17548,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7068 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7069 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7070 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7071 @@ -17587,9 +17582,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7081 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7082 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7083 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7084 @@ -17632,9 +17627,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7098 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7099 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7100 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7101 @@ -17666,9 +17661,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7111 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7112 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7113 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7114 @@ -17700,9 +17695,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7124 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7125 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7126 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7127 @@ -17745,9 +17740,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7141 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7142 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7143 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7144 @@ -17779,9 +17774,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7154 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7155 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7156 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7157 @@ -17813,9 +17808,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7167 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7168 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7169 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7170 @@ -17847,9 +17842,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 7180 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7181 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7182 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 7183 @@ -17881,7 +17876,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7193 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7195 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7196 @@ -17924,7 +17919,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7210 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7212 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7213 @@ -17967,7 +17962,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7227 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7229 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7230 @@ -18010,7 +18005,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7244 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7246 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7247 @@ -18064,7 +18059,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7265 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7267 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7268 @@ -18120,7 +18115,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DRAGON_TAMER, #line 7286 .trainerPic = TRAINER_PIC_DRAGON_TAMER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7288 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7289 @@ -18159,7 +18154,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7303 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7305 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7306 @@ -18191,7 +18186,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7316 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7318 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7319 @@ -18234,7 +18229,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7333 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7335 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7336 @@ -18266,7 +18261,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7346 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7348 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7349 @@ -18320,7 +18315,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7367 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7369 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7370 @@ -18352,7 +18347,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7380 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7382 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7383 @@ -18395,7 +18390,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7397 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7399 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7400 @@ -18438,7 +18433,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7414 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7416 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7417 @@ -18481,7 +18476,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7431 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7433 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7434 @@ -18513,7 +18508,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7444 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7446 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7447 @@ -18567,7 +18562,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7465 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7467 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7468 @@ -18610,7 +18605,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7482 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7484 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7485 @@ -18653,7 +18648,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7499 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7501 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7502 @@ -18696,7 +18691,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7516 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7518 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7519 @@ -18739,7 +18734,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7533 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7535 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7536 @@ -18782,7 +18777,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7550 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7552 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7553 @@ -18825,7 +18820,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 7567 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 7569 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7570 @@ -18857,7 +18852,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7580 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7582 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7583 @@ -18889,7 +18884,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7593 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7595 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7596 @@ -18932,9 +18927,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 7610 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7611 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7612 TRAINER_ENCOUNTER_MUSIC_COOL, #line 7613 @@ -18987,9 +18982,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 7631 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 7632 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7633 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 7634 @@ -19019,7 +19014,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7643 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7645 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7646 @@ -19092,7 +19087,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7675 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7677 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7678 @@ -19133,7 +19128,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7691 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7693 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7694 @@ -19221,7 +19216,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7728 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7730 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7731 @@ -19309,7 +19304,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7765 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7767 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7768 @@ -19395,7 +19390,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 7800 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7802 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 7803 @@ -19485,9 +19480,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7837 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7838 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7839 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7840 @@ -19519,9 +19514,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7850 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7851 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7852 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7853 @@ -19553,9 +19548,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7863 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7864 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7865 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7866 @@ -19598,9 +19593,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7880 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7881 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7882 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7883 @@ -19632,9 +19627,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7893 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7894 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7895 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7896 @@ -19666,9 +19661,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7906 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7907 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7908 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7909 @@ -19711,9 +19706,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7923 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7924 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7925 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7926 @@ -19756,9 +19751,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7940 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7941 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7942 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7943 @@ -19801,9 +19796,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 7957 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 7958 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7959 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 7960 @@ -19846,9 +19841,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 7974 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7975 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7976 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 7977 @@ -19887,9 +19882,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 7991 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 7992 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 7993 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 7994 @@ -19932,9 +19927,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 8008 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 8009 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8010 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 8011 @@ -19973,9 +19968,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 8025 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 8026 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8027 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 8028 @@ -20014,9 +20009,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 8042 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 8043 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8044 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 8045 @@ -20055,9 +20050,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 8059 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 8060 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8061 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 8062 @@ -20114,9 +20109,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 8084 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 8085 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8086 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 8087 @@ -20173,9 +20168,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8109 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8110 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8111 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8112 @@ -20218,9 +20213,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8126 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8127 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8128 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8129 @@ -20252,9 +20247,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8139 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8140 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8141 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8142 @@ -20286,9 +20281,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8152 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8153 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8154 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8155 @@ -20331,9 +20326,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8169 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8170 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8171 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8172 @@ -20365,9 +20360,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8182 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8183 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8184 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8185 @@ -20410,9 +20405,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8199 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8200 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8201 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8202 @@ -20444,9 +20439,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8212 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8213 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8214 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8215 @@ -20500,9 +20495,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8233 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8234 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8235 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8236 @@ -20534,9 +20529,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8246 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8247 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8248 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8249 @@ -20568,9 +20563,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8259 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8260 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8261 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8262 @@ -20602,9 +20597,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8272 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8273 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8274 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8275 @@ -20636,9 +20631,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8285 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8286 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8287 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8288 @@ -20681,9 +20676,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8302 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8303 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8304 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8305 @@ -20715,9 +20710,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8315 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8316 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8317 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8318 @@ -20760,9 +20755,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8332 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8333 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8334 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8335 @@ -20794,9 +20789,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8345 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8346 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8347 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8348 @@ -20828,9 +20823,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8358 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8359 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8360 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8361 @@ -20862,9 +20857,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8371 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8372 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8373 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8374 @@ -20907,9 +20902,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8388 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8389 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8390 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8391 @@ -20941,9 +20936,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8401 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8402 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8403 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8404 @@ -20986,9 +20981,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8418 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8419 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8420 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8421 @@ -21031,9 +21026,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8435 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8436 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8437 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8438 @@ -21076,9 +21071,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8452 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8453 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8454 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8455 @@ -21110,9 +21105,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8465 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8466 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8467 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8468 @@ -21144,9 +21139,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8478 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8479 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8480 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8481 @@ -21178,9 +21173,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8491 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8492 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8493 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8494 @@ -21223,9 +21218,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 8508 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 8509 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8510 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 8511 @@ -21279,9 +21274,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8529 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8530 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8531 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8532 @@ -21338,9 +21333,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8554 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8555 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8556 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8557 @@ -21397,9 +21392,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8579 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8580 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8581 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8582 @@ -21442,9 +21437,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8596 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8597 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8598 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8599 @@ -21487,9 +21482,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8613 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8614 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8615 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8616 @@ -21532,9 +21527,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8630 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8631 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8632 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8633 @@ -21588,7 +21583,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 8651 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 8653 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 8654 @@ -21627,9 +21622,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8668 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8669 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8670 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8671 @@ -21672,9 +21667,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8685 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8686 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8687 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8688 @@ -21728,9 +21723,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8706 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8707 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8708 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8709 @@ -21784,9 +21779,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8727 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8728 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8729 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8730 @@ -21840,9 +21835,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 8748 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 8749 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 8750 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 8751 @@ -21896,7 +21891,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8769 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8771 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8772 @@ -21939,7 +21934,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8786 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8788 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8789 @@ -21982,7 +21977,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8803 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8805 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8806 @@ -22025,7 +22020,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8820 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8822 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8823 @@ -22068,7 +22063,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8837 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8839 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8840 @@ -22111,7 +22106,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8854 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8856 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8857 @@ -22164,7 +22159,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8875 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8877 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8878 @@ -22207,7 +22202,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8892 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8894 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8895 @@ -22264,7 +22259,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 8917 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 8919 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 8920 @@ -22321,7 +22316,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 8942 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 8944 TRAINER_ENCOUNTER_MUSIC_MALE, #line 8945 @@ -22364,7 +22359,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 8959 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 8961 TRAINER_ENCOUNTER_MUSIC_MALE, #line 8962 @@ -22396,7 +22391,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 8972 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 8974 TRAINER_ENCOUNTER_MUSIC_MALE, #line 8975 @@ -22439,7 +22434,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 8989 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 8991 TRAINER_ENCOUNTER_MUSIC_MALE, #line 8992 @@ -22493,7 +22488,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9010 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9012 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9013 @@ -22536,7 +22531,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9027 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9029 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9030 @@ -22590,7 +22585,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9048 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9050 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9051 @@ -22633,7 +22628,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9065 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9067 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9068 @@ -22687,7 +22682,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9086 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9088 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9089 @@ -22741,7 +22736,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9107 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9109 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9110 @@ -22795,7 +22790,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9128 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9130 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9131 @@ -22849,7 +22844,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 9149 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 9151 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 9152 @@ -22881,9 +22876,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 9162 .trainerPic = TRAINER_PIC_POKEFAN_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 9163 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9164 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 9165 @@ -22944,9 +22939,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER_2, #line 9187 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 9188 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9189 TRAINER_ENCOUNTER_MUSIC_COOL, #line 9190 @@ -22980,7 +22975,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 9201 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9203 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9204 @@ -23019,9 +23014,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 9218 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9219 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9220 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9221 @@ -23060,7 +23055,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 9235 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9237 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 9238 @@ -23103,7 +23098,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9252 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9254 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9255 @@ -23146,9 +23141,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 9269 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 9270 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9271 TRAINER_ENCOUNTER_MUSIC_COOL, #line 9272 @@ -23189,9 +23184,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 9287 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 9288 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9289 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 9290 @@ -23234,7 +23229,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 9304 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9306 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9307 @@ -23266,7 +23261,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 9317 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9319 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 9320 @@ -23309,7 +23304,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9334 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9336 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9337 @@ -23352,7 +23347,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9351 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9353 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9354 @@ -23395,7 +23390,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_ADMIN, #line 9368 .trainerPic = TRAINER_PIC_MAGMA_ADMIN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9370 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 9371 @@ -23449,7 +23444,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9389 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9391 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9392 @@ -23492,7 +23487,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9406 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9408 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9409 @@ -23535,7 +23530,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9423 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9425 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9426 @@ -23578,7 +23573,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COLLECTOR, #line 9440 .trainerPic = TRAINER_PIC_COLLECTOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 9442 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 9443 @@ -23621,7 +23616,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9457 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9459 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9460 @@ -23734,7 +23729,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9507 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9509 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9510 @@ -23766,7 +23761,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9520 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9522 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9523 @@ -23820,7 +23815,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9541 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9543 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9544 @@ -23874,7 +23869,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9562 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9564 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9565 @@ -23906,7 +23901,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9575 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9577 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9578 @@ -23960,7 +23955,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9596 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9598 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9599 @@ -24014,7 +24009,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9617 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9619 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9620 @@ -24046,7 +24041,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9630 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9632 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9633 @@ -24100,7 +24095,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9651 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 9653 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9654 @@ -24154,9 +24149,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9672 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9673 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9674 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9675 @@ -24188,9 +24183,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9685 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9686 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9687 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9688 @@ -24244,9 +24239,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9706 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9707 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9708 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9709 @@ -24300,9 +24295,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9727 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9728 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9729 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9730 @@ -24334,9 +24329,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9740 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9741 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9742 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9743 @@ -24390,9 +24385,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9761 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9762 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9763 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9764 @@ -24446,9 +24441,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9782 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9783 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9784 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9785 @@ -24480,9 +24475,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9795 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9796 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9797 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9798 @@ -24536,9 +24531,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 9816 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 9817 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 9818 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 9819 @@ -24592,7 +24587,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 9837 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9839 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9840 @@ -24679,7 +24674,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 9870 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 9872 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9873 @@ -24711,7 +24706,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 9883 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9885 TRAINER_ENCOUNTER_MUSIC_COOL, #line 9886 @@ -24768,7 +24763,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 9908 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9910 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9911 @@ -24855,7 +24850,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 9941 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9943 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9944 @@ -24942,7 +24937,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 9974 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 9976 TRAINER_ENCOUNTER_MUSIC_MALE, #line 9977 @@ -25029,7 +25024,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10007 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10009 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10010 @@ -25116,9 +25111,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10040 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10041 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10042 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10043 @@ -25205,9 +25200,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 10073 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10074 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10075 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10076 @@ -25252,7 +25247,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 10091 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 10093 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 10094 @@ -25284,9 +25279,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10104 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10105 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10106 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10107 @@ -25373,9 +25368,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10137 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10138 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10139 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10140 @@ -25462,9 +25457,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10170 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10171 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10172 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10173 @@ -25551,9 +25546,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 10203 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10204 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10205 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10206 @@ -25640,7 +25635,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10236 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10238 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10239 @@ -25674,7 +25669,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10250 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10252 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10253 @@ -25730,7 +25725,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10272 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10274 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10275 @@ -25764,7 +25759,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10286 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10288 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10289 @@ -25798,7 +25793,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10300 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10302 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10303 @@ -25832,7 +25827,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10314 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10316 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10317 @@ -25866,7 +25861,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10328 .trainerPic = TRAINER_PIC_POKEMON_RANGER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10330 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10331 @@ -25911,9 +25906,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10346 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10347 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10348 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10349 @@ -25958,9 +25953,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10364 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10365 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10366 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10367 @@ -26016,9 +26011,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10386 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10387 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10388 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10389 @@ -26063,9 +26058,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10404 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10405 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10406 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10407 @@ -26110,9 +26105,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10422 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10423 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10424 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10425 @@ -26157,9 +26152,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10440 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10441 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10442 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10443 @@ -26204,9 +26199,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_RANGER, #line 10458 .trainerPic = TRAINER_PIC_POKEMON_RANGER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10459 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10460 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10461 @@ -26251,7 +26246,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 10476 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10478 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10479 @@ -26283,7 +26278,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 10489 .trainerPic = TRAINER_PIC_AQUA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10491 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 10492 @@ -26326,9 +26321,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10506 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10507 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10508 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 10509 @@ -26371,9 +26366,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 10523 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10524 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10525 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 10526 @@ -26416,7 +26411,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10540 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10542 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10543 @@ -26459,7 +26454,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 10557 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 10559 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 10560 @@ -26502,7 +26497,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 10574 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 10576 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10577 @@ -26534,9 +26529,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 10587 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 10588 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10589 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10590 @@ -26568,7 +26563,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 10600 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 10602 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10603 @@ -26600,9 +26595,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 10613 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 10614 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10615 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 10616 @@ -26634,7 +26629,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 10626 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10628 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 10629 @@ -26666,9 +26661,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 10639 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10640 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10641 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10642 @@ -26724,7 +26719,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 10662 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10664 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 10665 @@ -26756,7 +26751,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10675 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10677 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10678 @@ -26788,7 +26783,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 10688 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10690 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 10691 @@ -26820,9 +26815,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 10701 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10702 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10703 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10704 @@ -26854,7 +26849,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 10714 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10716 TRAINER_ENCOUNTER_MUSIC_RICH, #line 10717 @@ -26886,9 +26881,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HEX_MANIAC, #line 10727 .trainerPic = TRAINER_PIC_HEX_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 10728 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10729 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 10730 @@ -26920,7 +26915,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 10740 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10742 TRAINER_ENCOUNTER_MUSIC_RICH, #line 10743 @@ -26952,7 +26947,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 10753 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10755 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10756 @@ -26984,9 +26979,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10766 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10767 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10768 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10769 @@ -27029,7 +27024,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10783 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10785 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10786 @@ -27061,7 +27056,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10796 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10798 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10799 @@ -27093,7 +27088,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10809 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10811 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10812 @@ -27125,7 +27120,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 10822 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10824 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10825 @@ -27157,9 +27152,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 10835 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10836 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10837 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10838 @@ -27191,7 +27186,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 10848 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10850 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10851 @@ -27234,7 +27229,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 10865 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10867 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10868 @@ -27277,7 +27272,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 10882 .trainerPic = TRAINER_PIC_EXPERT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10884 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 10885 @@ -27320,9 +27315,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 10899 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10900 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10901 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 10902 @@ -27354,9 +27349,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_AQUA, #line 10912 .trainerPic = TRAINER_PIC_AQUA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 10913 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10914 TRAINER_ENCOUNTER_MUSIC_AQUA, #line 10915 @@ -27399,7 +27394,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_ADMIN, #line 10929 .trainerPic = TRAINER_PIC_MAGMA_ADMIN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10931 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 10932 @@ -27464,7 +27459,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 10954 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 10956 TRAINER_ENCOUNTER_MUSIC_COOL, #line 10957 @@ -27509,7 +27504,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 10972 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 10974 TRAINER_ENCOUNTER_MUSIC_MALE, #line 10975 @@ -27552,9 +27547,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 10989 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 10990 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 10991 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 10992 @@ -27597,7 +27592,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_LEADER, #line 11006 .trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11008 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 11009 @@ -27653,7 +27648,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_LEADER, #line 11028 .trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11030 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 11031 @@ -27709,9 +27704,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11050 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11051 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11052 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11053 @@ -27754,9 +27749,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11067 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11068 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11069 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11070 @@ -27799,9 +27794,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11084 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11085 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11086 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11087 @@ -27833,9 +27828,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_WINSTRATE, #line 11097 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11098 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11099 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11100 @@ -27889,9 +27884,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11118 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11119 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11120 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11121 @@ -27934,9 +27929,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11135 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11136 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11137 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11138 @@ -27979,9 +27974,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11152 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11153 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11154 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11155 @@ -28024,9 +28019,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11169 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11170 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11171 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11172 @@ -28080,9 +28075,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11190 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11191 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11192 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11193 @@ -28114,9 +28109,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11203 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11204 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11205 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11206 @@ -28170,9 +28165,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11224 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11225 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11226 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11227 @@ -28204,9 +28199,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LASS, #line 11237 .trainerPic = TRAINER_PIC_LASS, - .encounterMusic_gender = + .encounterMusic_gender = #line 11238 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11239 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11240 @@ -28249,7 +28244,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11254 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11256 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11257 @@ -28292,7 +28287,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11271 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11273 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11274 @@ -28357,7 +28352,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11296 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11298 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11299 @@ -28400,7 +28395,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11313 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11315 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11316 @@ -28443,7 +28438,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11330 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11332 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11333 @@ -28486,7 +28481,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11347 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11349 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11350 @@ -28518,7 +28513,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11360 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11362 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11363 @@ -28561,7 +28556,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11377 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11379 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11380 @@ -28593,7 +28588,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11390 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11392 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11393 @@ -28636,7 +28631,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11407 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11409 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11410 @@ -28690,7 +28685,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_CATCHER, #line 11428 .trainerPic = TRAINER_PIC_BUG_CATCHER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11430 TRAINER_ENCOUNTER_MUSIC_MALE, #line 11431 @@ -28755,7 +28750,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11453 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11455 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11456 @@ -28798,7 +28793,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11470 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11472 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11473 @@ -28852,7 +28847,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11491 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11493 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11494 @@ -28895,7 +28890,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11508 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11510 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11511 @@ -28938,7 +28933,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11525 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11527 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11528 @@ -28992,7 +28987,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11546 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11548 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11549 @@ -29024,7 +29019,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11559 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11561 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11562 @@ -29067,7 +29062,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11576 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11578 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11579 @@ -29104,7 +29099,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11591 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11593 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11594 @@ -29157,7 +29152,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11612 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11614 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11615 @@ -29211,7 +29206,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11633 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11635 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11636 @@ -29276,7 +29271,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11658 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11660 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11661 @@ -29341,7 +29336,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11683 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11685 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11686 @@ -29406,7 +29401,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 11708 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 11710 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 11711 @@ -29471,7 +29466,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11733 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11735 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11736 @@ -29514,7 +29509,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11750 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11752 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11753 @@ -29557,7 +29552,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11767 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11769 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11770 @@ -29600,7 +29595,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11784 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11786 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11787 @@ -29643,7 +29638,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11801 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11803 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11804 @@ -29686,7 +29681,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11818 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11820 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11821 @@ -29729,7 +29724,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 11835 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 11837 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 11838 @@ -29772,9 +29767,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 11852 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 11853 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11854 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 11855 @@ -29806,7 +29801,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 11865 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 11867 TRAINER_ENCOUNTER_MUSIC_COOL, #line 11868 @@ -29847,9 +29842,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 11883 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 11884 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11885 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 11886 @@ -29906,9 +29901,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 11908 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 11909 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 11910 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 11911 @@ -29947,7 +29942,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 11925 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 11927 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 11928 @@ -30004,7 +29999,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 11950 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 11952 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 11953 @@ -30061,7 +30056,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 11975 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 11977 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 11978 @@ -30118,7 +30113,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 12000 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 12002 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12003 @@ -30161,9 +30156,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 12017 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 12018 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12019 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 12020 @@ -30217,7 +30212,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12038 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12040 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12041 @@ -30249,7 +30244,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12051 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12053 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12054 @@ -30362,7 +30357,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12101 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12103 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12104 @@ -30475,7 +30470,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12151 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12153 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12154 @@ -30588,7 +30583,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12201 .trainerPic = TRAINER_PIC_WALLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12203 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12204 @@ -30701,7 +30696,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12251 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12253 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12254 @@ -30766,7 +30761,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12276 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12278 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12279 @@ -30831,7 +30826,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12301 .trainerPic = TRAINER_PIC_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12303 TRAINER_ENCOUNTER_MUSIC_MALE, #line 12304 @@ -30896,9 +30891,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12326 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12327 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12328 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 12329 @@ -30963,9 +30958,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12351 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12352 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12353 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 12354 @@ -31030,9 +31025,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 12376 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12377 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12378 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 12379 @@ -31097,7 +31092,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12401 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12403 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12404 @@ -31151,7 +31146,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12422 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12424 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12425 @@ -31194,7 +31189,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12439 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12441 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12442 @@ -31248,9 +31243,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 12460 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 12461 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12462 TRAINER_ENCOUNTER_MUSIC_COOL, #line 12463 @@ -31295,7 +31290,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 12478 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 12480 TRAINER_ENCOUNTER_MUSIC_COOL, #line 12481 @@ -31340,7 +31335,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 12496 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 12498 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12499 @@ -31372,7 +31367,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12509 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12511 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12512 @@ -31426,7 +31421,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 12530 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 12532 TRAINER_ENCOUNTER_MUSIC_COOL, #line 12533 @@ -31469,7 +31464,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 12547 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 12549 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12550 @@ -31512,9 +31507,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 12564 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 12565 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12566 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12567 @@ -31546,7 +31541,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TWINS, #line 12577 .trainerPic = TRAINER_PIC_TWINS, - .encounterMusic_gender = + .encounterMusic_gender = #line 12579 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 12580 @@ -31589,7 +31584,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 12594 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 12596 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 12597 @@ -31646,7 +31641,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SR_AND_JR, #line 12619 .trainerPic = TRAINER_PIC_SR_AND_JR, - .encounterMusic_gender = + .encounterMusic_gender = #line 12621 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 12622 @@ -31703,7 +31698,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNG_COUPLE, #line 12644 .trainerPic = TRAINER_PIC_YOUNG_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12646 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 12647 @@ -31760,7 +31755,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_OLD_COUPLE, #line 12669 .trainerPic = TRAINER_PIC_OLD_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12671 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12672 @@ -31817,7 +31812,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_OLD_COUPLE, #line 12694 .trainerPic = TRAINER_PIC_OLD_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12696 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12697 @@ -31874,7 +31869,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_OLD_COUPLE, #line 12719 .trainerPic = TRAINER_PIC_OLD_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12721 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12722 @@ -31931,7 +31926,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_OLD_COUPLE, #line 12744 .trainerPic = TRAINER_PIC_OLD_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12746 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12747 @@ -31988,7 +31983,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_OLD_COUPLE, #line 12769 .trainerPic = TRAINER_PIC_OLD_COUPLE, - .encounterMusic_gender = + .encounterMusic_gender = #line 12771 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 12772 @@ -32045,7 +32040,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12794 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12796 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12797 @@ -32088,7 +32083,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12811 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12813 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12814 @@ -32131,7 +32126,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12828 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12830 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12831 @@ -32174,7 +32169,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12845 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12847 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12848 @@ -32217,7 +32212,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12862 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12864 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12865 @@ -32260,7 +32255,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12879 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12881 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12882 @@ -32303,7 +32298,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SIS_AND_BRO, #line 12896 .trainerPic = TRAINER_PIC_SIS_AND_BRO, - .encounterMusic_gender = + .encounterMusic_gender = #line 12898 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 12899 @@ -32346,7 +32341,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12913 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12915 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12916 @@ -32411,7 +32406,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RICH_BOY, #line 12938 .trainerPic = TRAINER_PIC_RICH_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12940 TRAINER_ENCOUNTER_MUSIC_RICH, #line 12941 @@ -32456,9 +32451,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LADY, #line 12955 .trainerPic = TRAINER_PIC_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 12956 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12957 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 12958 @@ -32505,7 +32500,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 12973 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 12975 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 12976 @@ -32537,9 +32532,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_F, #line 12986 .trainerPic = TRAINER_PIC_TUBER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 12987 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 12988 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 12989 @@ -32571,7 +32566,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TUBER_M, #line 12999 .trainerPic = TRAINER_PIC_TUBER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13001 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13002 @@ -32614,7 +32609,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEFAN, #line 13016 .trainerPic = TRAINER_PIC_POKEFAN_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13018 TRAINER_ENCOUNTER_MUSIC_TWINS, #line 13019 @@ -32661,7 +32656,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 13033 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 13035 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13036 @@ -32704,9 +32699,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 13050 .trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13051 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13052 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13053 @@ -32738,7 +32733,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 13063 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 13065 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13066 @@ -32770,7 +32765,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 13076 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 13078 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13079 @@ -32802,7 +32797,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 13089 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13091 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13092 @@ -32834,9 +32829,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 13102 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 13103 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13104 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13105 @@ -32868,9 +32863,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 13115 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13116 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13117 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13118 @@ -32902,7 +32897,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 13128 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13130 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13131 @@ -32934,9 +32929,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 13141 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13142 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13143 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13144 @@ -32979,7 +32974,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 13158 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13160 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13161 @@ -33022,7 +33017,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 13175 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13177 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13178 @@ -33065,7 +33060,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_POKEMANIAC, #line 13192 .trainerPic = TRAINER_PIC_POKEMANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 13194 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 13195 @@ -33108,9 +33103,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 13209 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13210 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13211 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13212 @@ -33153,7 +33148,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FISHERMAN, #line 13226 .trainerPic = TRAINER_PIC_FISHERMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 13228 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13229 @@ -33185,9 +33180,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 13239 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13240 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13241 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13242 @@ -33219,7 +33214,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 13252 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13254 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13255 @@ -33273,7 +33268,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13273 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13275 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13276 @@ -33305,7 +33300,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13286 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13288 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13289 @@ -33337,7 +33332,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13299 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13301 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13302 @@ -33369,7 +33364,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13312 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13314 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13315 @@ -33412,7 +33407,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13329 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13331 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13332 @@ -33455,7 +33450,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13346 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13348 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13349 @@ -33487,7 +33482,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13359 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13361 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13362 @@ -33519,7 +33514,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13372 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13374 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13375 @@ -33551,7 +33546,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13385 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13387 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13388 @@ -33583,7 +33578,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13398 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13400 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13401 @@ -33615,7 +33610,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13411 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13413 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13414 @@ -33647,7 +33642,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13424 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13426 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13427 @@ -33679,7 +33674,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13437 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13439 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13440 @@ -33711,9 +33706,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13450 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13451 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13452 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13453 @@ -33745,9 +33740,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13463 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13464 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13465 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13466 @@ -33779,9 +33774,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TEAM_MAGMA, #line 13476 .trainerPic = TRAINER_PIC_MAGMA_GRUNT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13477 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13478 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13479 @@ -33813,7 +33808,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_ADMIN, #line 13489 .trainerPic = TRAINER_PIC_MAGMA_ADMIN, - .encounterMusic_gender = + .encounterMusic_gender = #line 13491 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13492 @@ -33878,9 +33873,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 13514 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13515 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13516 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13517 @@ -33925,7 +33920,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_MAGMA_LEADER, #line 13532 .trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE, - .encounterMusic_gender = + .encounterMusic_gender = #line 13534 TRAINER_ENCOUNTER_MUSIC_MAGMA, #line 13535 @@ -33979,7 +33974,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_M, #line 13553 .trainerPic = TRAINER_PIC_SWIMMER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13555 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 13556 @@ -34011,9 +34006,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SWIMMER_F, #line 13566 .trainerPic = TRAINER_PIC_SWIMMER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13567 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13568 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 13569 @@ -34045,7 +34040,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 13579 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 13581 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13582 @@ -34088,7 +34083,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 13596 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13598 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13599 @@ -34131,7 +34126,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 13613 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13615 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 13616 @@ -34163,7 +34158,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 13626 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 13628 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13629 @@ -34217,9 +34212,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 13647 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13648 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13649 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13650 @@ -34275,7 +34270,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 13669 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13671 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13672 @@ -34318,9 +34313,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PICNICKER, #line 13686 .trainerPic = TRAINER_PIC_PICNICKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13687 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13688 TRAINER_ENCOUNTER_MUSIC_GIRL, #line 13689 @@ -34363,7 +34358,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 13703 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 13705 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13706 @@ -34406,7 +34401,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_CAMPER, #line 13720 .trainerPic = TRAINER_PIC_CAMPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13722 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13723 @@ -34449,7 +34444,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 13737 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13739 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13740 @@ -34492,9 +34487,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_AROMA_LADY, #line 13754 .trainerPic = TRAINER_PIC_AROMA_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 13755 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13756 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13757 @@ -34537,9 +34532,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 13771 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13772 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13773 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13774 @@ -34582,7 +34577,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_NINJA_BOY, #line 13788 .trainerPic = TRAINER_PIC_NINJA_BOY, - .encounterMusic_gender = + .encounterMusic_gender = #line 13790 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 13791 @@ -34625,9 +34620,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 13805 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13806 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13807 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13808 @@ -34670,9 +34665,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 13822 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 13823 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13824 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13825 @@ -34715,9 +34710,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 13839 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13840 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13841 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13842 @@ -34760,7 +34755,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 13856 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13858 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13859 @@ -34803,7 +34798,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_YOUNGSTER, #line 13873 .trainerPic = TRAINER_PIC_YOUNGSTER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13875 TRAINER_ENCOUNTER_MUSIC_MALE, #line 13876 @@ -34846,9 +34841,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 13890 .trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13891 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13892 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13893 @@ -34880,9 +34875,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 13903 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13904 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13905 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13906 @@ -34914,9 +34909,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 13916 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 13917 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13918 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13919 @@ -34948,9 +34943,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_EXPERT, #line 13929 .trainerPic = TRAINER_PIC_EXPERT_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 13930 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13931 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13932 @@ -34995,7 +34990,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 13947 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 13949 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 13950 @@ -35027,7 +35022,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_KINDLER, #line 13960 .trainerPic = TRAINER_PIC_KINDLER, - .encounterMusic_gender = + .encounterMusic_gender = #line 13962 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 13963 @@ -35070,9 +35065,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PARASOL_LADY, #line 13977 .trainerPic = TRAINER_PIC_PARASOL_LADY, - .encounterMusic_gender = + .encounterMusic_gender = #line 13978 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 13979 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 13980 @@ -35104,7 +35099,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 13990 .trainerPic = TRAINER_PIC_COOLTRAINER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 13992 TRAINER_ENCOUNTER_MUSIC_COOL, #line 13993 @@ -35144,9 +35139,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BATTLE_GIRL, #line 14007 .trainerPic = TRAINER_PIC_BATTLE_GIRL, - .encounterMusic_gender = + .encounterMusic_gender = #line 14008 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14009 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 14010 @@ -35189,7 +35184,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 14024 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 14026 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 14027 @@ -35232,7 +35227,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 14041 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 14043 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14044 @@ -35319,9 +35314,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 14074 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 14075 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14076 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14077 @@ -35408,9 +35403,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 14107 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 14108 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14109 TRAINER_ENCOUNTER_MUSIC_COOL, #line 14110 @@ -35455,9 +35450,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 14125 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14126 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14127 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14128 @@ -35500,9 +35495,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 14142 .trainerPic = TRAINER_PIC_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14143 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14144 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14145 @@ -35545,9 +35540,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14159 .trainerPic = TRAINER_PIC_LEADER_ROXANNE, - .encounterMusic_gender = + .encounterMusic_gender = #line 14160 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14161 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14162 @@ -35646,9 +35641,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14201 .trainerPic = TRAINER_PIC_LEADER_ROXANNE, - .encounterMusic_gender = + .encounterMusic_gender = #line 14202 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14203 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14204 @@ -35765,9 +35760,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14251 .trainerPic = TRAINER_PIC_LEADER_ROXANNE, - .encounterMusic_gender = + .encounterMusic_gender = #line 14252 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14253 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14254 @@ -35884,9 +35879,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14301 .trainerPic = TRAINER_PIC_LEADER_ROXANNE, - .encounterMusic_gender = + .encounterMusic_gender = #line 14302 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14303 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14304 @@ -36021,7 +36016,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14359 .trainerPic = TRAINER_PIC_LEADER_BRAWLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14361 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14362 @@ -36120,7 +36115,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14401 .trainerPic = TRAINER_PIC_LEADER_BRAWLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14403 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14404 @@ -36219,7 +36214,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14443 .trainerPic = TRAINER_PIC_LEADER_BRAWLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14445 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14446 @@ -36336,7 +36331,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14493 .trainerPic = TRAINER_PIC_LEADER_BRAWLY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14495 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14496 @@ -36471,7 +36466,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14551 .trainerPic = TRAINER_PIC_LEADER_WATTSON, - .encounterMusic_gender = + .encounterMusic_gender = #line 14553 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14554 @@ -36570,7 +36565,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14593 .trainerPic = TRAINER_PIC_LEADER_WATTSON, - .encounterMusic_gender = + .encounterMusic_gender = #line 14595 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14596 @@ -36687,7 +36682,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14643 .trainerPic = TRAINER_PIC_LEADER_WATTSON, - .encounterMusic_gender = + .encounterMusic_gender = #line 14645 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14646 @@ -36804,7 +36799,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14693 .trainerPic = TRAINER_PIC_LEADER_WATTSON, - .encounterMusic_gender = + .encounterMusic_gender = #line 14695 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14696 @@ -36939,9 +36934,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14751 .trainerPic = TRAINER_PIC_LEADER_FLANNERY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14752 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14753 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14754 @@ -37042,9 +37037,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14793 .trainerPic = TRAINER_PIC_LEADER_FLANNERY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14794 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14795 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14796 @@ -37163,9 +37158,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14843 .trainerPic = TRAINER_PIC_LEADER_FLANNERY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14844 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14845 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14846 @@ -37302,9 +37297,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14901 .trainerPic = TRAINER_PIC_LEADER_FLANNERY, - .encounterMusic_gender = + .encounterMusic_gender = #line 14902 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 14903 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 14904 @@ -37441,7 +37436,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 14959 .trainerPic = TRAINER_PIC_LEADER_NORMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 14961 TRAINER_ENCOUNTER_MUSIC_MALE, #line 14962 @@ -37540,7 +37535,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15001 .trainerPic = TRAINER_PIC_LEADER_NORMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15003 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15004 @@ -37657,7 +37652,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15051 .trainerPic = TRAINER_PIC_LEADER_NORMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15053 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15054 @@ -37774,7 +37769,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15101 .trainerPic = TRAINER_PIC_LEADER_NORMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15103 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15104 @@ -37909,9 +37904,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15159 .trainerPic = TRAINER_PIC_LEADER_WINONA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15160 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15161 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15162 @@ -38028,9 +38023,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15209 .trainerPic = TRAINER_PIC_LEADER_WINONA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15210 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15211 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15212 @@ -38165,9 +38160,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15267 .trainerPic = TRAINER_PIC_LEADER_WINONA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15268 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15269 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15270 @@ -38302,9 +38297,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15325 .trainerPic = TRAINER_PIC_LEADER_WINONA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15326 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15327 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15328 @@ -38439,7 +38434,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15383 .trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15385 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15386 @@ -38558,7 +38553,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15433 .trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15435 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15436 @@ -38695,7 +38690,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15491 .trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15493 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15494 @@ -38832,7 +38827,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15549 .trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15551 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 15552 @@ -38969,7 +38964,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15607 .trainerPic = TRAINER_PIC_LEADER_JUAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15609 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15610 @@ -39086,7 +39081,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15657 .trainerPic = TRAINER_PIC_LEADER_JUAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15659 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15660 @@ -39203,7 +39198,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15707 .trainerPic = TRAINER_PIC_LEADER_JUAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15709 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15710 @@ -39338,7 +39333,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_LEADER, #line 15765 .trainerPic = TRAINER_PIC_LEADER_JUAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15767 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15768 @@ -39473,7 +39468,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BUG_MANIAC, #line 15823 .trainerPic = TRAINER_PIC_BUG_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 15825 TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS, #line 15826 @@ -39528,7 +39523,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BIRD_KEEPER, #line 15846 .trainerPic = TRAINER_PIC_BIRD_KEEPER, - .encounterMusic_gender = + .encounterMusic_gender = #line 15848 TRAINER_ENCOUNTER_MUSIC_COOL, #line 15849 @@ -39560,7 +39555,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 15859 .trainerPic = TRAINER_PIC_STEVEN, - .encounterMusic_gender = + .encounterMusic_gender = #line 15861 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15862 @@ -39693,9 +39688,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SALON_MAIDEN, #line 15917 .trainerPic = TRAINER_PIC_SALON_MAIDEN_ANABEL, - .encounterMusic_gender = + .encounterMusic_gender = #line 15918 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15919 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15920 @@ -39727,7 +39722,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_DOME_ACE, #line 15930 .trainerPic = TRAINER_PIC_DOME_ACE_TUCKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 15932 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15933 @@ -39759,7 +39754,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PALACE_MAVEN, #line 15943 .trainerPic = TRAINER_PIC_PALACE_MAVEN_SPENSER, - .encounterMusic_gender = + .encounterMusic_gender = #line 15945 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15946 @@ -39791,9 +39786,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_ARENA_TYCOON, #line 15956 .trainerPic = TRAINER_PIC_ARENA_TYCOON_GRETA, - .encounterMusic_gender = + .encounterMusic_gender = #line 15957 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15958 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15959 @@ -39825,7 +39820,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_FACTORY_HEAD, #line 15969 .trainerPic = TRAINER_PIC_FACTORY_HEAD_NOLAND, - .encounterMusic_gender = + .encounterMusic_gender = #line 15971 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15972 @@ -39857,9 +39852,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PIKE_QUEEN, #line 15982 .trainerPic = TRAINER_PIC_PIKE_QUEEN_LUCY, - .encounterMusic_gender = + .encounterMusic_gender = #line 15983 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 15984 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15985 @@ -39891,7 +39886,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PYRAMID_KING, #line 15995 .trainerPic = TRAINER_PIC_PYRAMID_KING_BRANDON, - .encounterMusic_gender = + .encounterMusic_gender = #line 15997 TRAINER_ENCOUNTER_MUSIC_MALE, #line 15998 @@ -39923,7 +39918,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 16008 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 16010 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16011 @@ -39966,7 +39961,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 16025 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 16027 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16028 @@ -40020,7 +40015,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 16046 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 16048 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16049 @@ -40074,7 +40069,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RUIN_MANIAC, #line 16067 .trainerPic = TRAINER_PIC_RUIN_MANIAC, - .encounterMusic_gender = + .encounterMusic_gender = #line 16069 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16070 @@ -40128,7 +40123,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 16088 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 16090 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16091 @@ -40182,7 +40177,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 16109 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 16111 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16112 @@ -40236,7 +40231,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 16130 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 16132 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16133 @@ -40290,7 +40285,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_SAILOR, #line 16151 .trainerPic = TRAINER_PIC_SAILOR, - .encounterMusic_gender = + .encounterMusic_gender = #line 16153 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16154 @@ -40344,7 +40339,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 16172 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 16174 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 16175 @@ -40387,7 +40382,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 16189 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 16191 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 16192 @@ -40441,7 +40436,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 16210 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 16212 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 16213 @@ -40495,7 +40490,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_TRIATHLETE, #line 16231 .trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 16233 TRAINER_ENCOUNTER_MUSIC_SWIMMER, #line 16234 @@ -40549,7 +40544,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 16252 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 16254 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16255 @@ -40592,7 +40587,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 16269 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 16271 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16272 @@ -40646,7 +40641,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 16290 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 16292 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16293 @@ -40700,7 +40695,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BLACK_BELT, #line 16311 .trainerPic = TRAINER_PIC_BLACK_BELT, - .encounterMusic_gender = + .encounterMusic_gender = #line 16313 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16314 @@ -40754,9 +40749,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 16332 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16333 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16334 TRAINER_ENCOUNTER_MUSIC_COOL, #line 16335 @@ -40801,9 +40796,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 16350 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16351 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16352 TRAINER_ENCOUNTER_MUSIC_COOL, #line 16353 @@ -40859,9 +40854,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 16372 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16373 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16374 TRAINER_ENCOUNTER_MUSIC_COOL, #line 16375 @@ -40917,9 +40912,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_COOLTRAINER, #line 16394 .trainerPic = TRAINER_PIC_COOLTRAINER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16395 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16396 TRAINER_ENCOUNTER_MUSIC_COOL, #line 16397 @@ -40975,7 +40970,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 16416 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 16418 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16419 @@ -41029,7 +41024,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 16437 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 16439 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16440 @@ -41083,7 +41078,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 16458 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 16460 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16461 @@ -41137,7 +41132,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GUITARIST, #line 16479 .trainerPic = TRAINER_PIC_GUITARIST, - .encounterMusic_gender = + .encounterMusic_gender = #line 16481 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16482 @@ -41191,7 +41186,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 16500 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 16502 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16503 @@ -41234,7 +41229,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 16517 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 16519 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16520 @@ -41288,7 +41283,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 16538 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 16540 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16541 @@ -41342,7 +41337,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_HIKER, #line 16559 .trainerPic = TRAINER_PIC_HIKER, - .encounterMusic_gender = + .encounterMusic_gender = #line 16561 TRAINER_ENCOUNTER_MUSIC_HIKER, #line 16562 @@ -41396,9 +41391,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 16580 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16581 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16582 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16583 @@ -41485,9 +41480,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 16613 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16614 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16615 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16616 @@ -41574,9 +41569,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 16646 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16647 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16648 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16649 @@ -41663,9 +41658,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PKMN_BREEDER, #line 16679 .trainerPic = TRAINER_PIC_POKEMON_BREEDER_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16680 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16681 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16682 @@ -41752,9 +41747,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 16712 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 16713 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16714 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16715 @@ -41797,9 +41792,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 16729 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 16730 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16731 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16732 @@ -41853,9 +41848,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 16750 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 16751 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16752 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16753 @@ -41909,9 +41904,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_BEAUTY, #line 16771 .trainerPic = TRAINER_PIC_BEAUTY, - .encounterMusic_gender = + .encounterMusic_gender = #line 16772 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16773 TRAINER_ENCOUNTER_MUSIC_FEMALE, #line 16774 @@ -41965,9 +41960,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 16792 .trainerPic = TRAINER_PIC_PSYCHIC_F, - .encounterMusic_gender = + .encounterMusic_gender = #line 16793 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16794 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16795 @@ -41997,7 +41992,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_PSYCHIC, #line 16804 .trainerPic = TRAINER_PIC_PSYCHIC_M, - .encounterMusic_gender = + .encounterMusic_gender = #line 16806 TRAINER_ENCOUNTER_MUSIC_INTENSE, #line 16807 @@ -42038,7 +42033,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_GENTLEMAN, #line 16820 .trainerPic = TRAINER_PIC_GENTLEMAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 16822 TRAINER_ENCOUNTER_MUSIC_RICH, #line 16823 @@ -42068,7 +42063,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 16832 .trainerPic = TRAINER_PIC_RED, - .encounterMusic_gender = + .encounterMusic_gender = #line 16834 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16835 @@ -42098,9 +42093,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RIVAL, #line 16844 .trainerPic = TRAINER_PIC_LEAF, - .encounterMusic_gender = + .encounterMusic_gender = #line 16845 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16846 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16847 @@ -42130,7 +42125,7 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RS_PROTAG, #line 16856 .trainerPic = TRAINER_PIC_RS_BRENDAN, - .encounterMusic_gender = + .encounterMusic_gender = #line 16858 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16859 @@ -42160,9 +42155,9 @@ F_TRAINER_FEMALE | .trainerClass = TRAINER_CLASS_RS_PROTAG, #line 16868 .trainerPic = TRAINER_PIC_RS_MAY, - .encounterMusic_gender = + .encounterMusic_gender = #line 16869 -F_TRAINER_FEMALE | +F_TRAINER_FEMALE | #line 16870 TRAINER_ENCOUNTER_MUSIC_MALE, #line 16871 diff --git a/src/data/wild_encounters.json.txt b/src/data/wild_encounters.json.txt index bf848249f0..20ac1c7889 100755 --- a/src/data/wild_encounters.json.txt +++ b/src/data/wild_encounters.json.txt @@ -64,8 +64,19 @@ const struct WildPokemon {{ encounter.base_label }}_FishingMons[] = const struct WildPokemonInfo {{ encounter.base_label }}_FishingMonsInfo = { {{encounter.fishing_mons.encounter_rate}}, {{ encounter.base_label }}_FishingMons }; {% endif %} -## endfor +{% if existsIn(encounter, "hidden_mons") %} +const struct WildPokemon {{ encounter.base_label }}_HiddenMons[] = +{ +## for wild_mon in encounter.hidden_mons.mons + { {{ wild_mon.min_level }}, {{ wild_mon.max_level }}, {{ wild_mon.species }} }, +## endfor +}; + +const struct WildPokemonInfo {{ encounter.base_label }}_HiddenMonsInfo = { {{encounter.hidden_mons.encounter_rate}}, {{ encounter.base_label }}_HiddenMons }; +{% endif %} + +## endfor const struct WildPokemonHeader {{ wild_encounter_group.label }}[] = { ## for encounter in wild_encounter_group.encounters @@ -76,6 +87,7 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] = .waterMonsInfo = {% if existsIn(encounter, "water_mons") %}&{{ encounter.base_label }}_WaterMonsInfo{% else %}NULL{% endif %}, .rockSmashMonsInfo = {% if existsIn(encounter, "rock_smash_mons") %}&{{ encounter.base_label }}_RockSmashMonsInfo{% else %}NULL{% endif %}, .fishingMonsInfo = {% if existsIn(encounter, "fishing_mons") %}&{{ encounter.base_label }}_FishingMonsInfo{% else %}NULL{% endif %}, + .hiddenMonsInfo = {% if existsIn(encounter, "hidden_mons") %}&{{ encounter.base_label }}_HiddenMonsInfo{% else %}NULL{% endif %}, }, ## endfor { @@ -85,6 +97,7 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] = .waterMonsInfo = NULL, .rockSmashMonsInfo = NULL, .fishingMonsInfo = NULL, + .hiddenMonsInfo = NULL, }, }; ## endfor diff --git a/src/daycare.c b/src/daycare.c index 912537af56..83dd24af07 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -33,7 +33,6 @@ static void ClearDaycareMonMail(struct DaycareMail *mail); static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare); static void DaycarePrintMonInfo(u8 windowId, u32 daycareSlotId, u8 y); static u8 ModifyBreedingScoreForOvalCharm(u8 score); -static u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves); static u16 GetEggSpecies(u16 species); // RAM buffers used to assist with BuildEggMoveset() @@ -590,27 +589,6 @@ static void UNUSED TriggerPendingDaycareMaleEgg(void) _TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare); } -// Removes the selected index from the given IV list and shifts the remaining -// elements to the left. -static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) -{ - s32 i, j; - u8 temp[NUM_STATS]; - - ivs[selectedIv] = 0xFF; - for (i = 0; i < NUM_STATS; i++) - { - temp[i] = ivs[i]; - } - - j = 0; - for (i = 0; i < NUM_STATS; i++) - { - if (temp[i] != 0xFF) - ivs[j++] = temp[i]; - } -} - static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare) { u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM); @@ -772,7 +750,7 @@ static void InheritAbility(struct Pokemon *egg, struct BoxPokemon *father, struc // Counts the number of egg moves a Pokémon learns and stores the moves in // the given array. -static u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves) +u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves) { u16 numEggMoves; u16 species; diff --git a/src/debug.c b/src/debug.c index 3615ef1997..9e24846d6a 100644 --- a/src/debug.c +++ b/src/debug.c @@ -158,6 +158,7 @@ enum FlagsVarsDebugMenu DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL, + DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER, @@ -412,6 +413,7 @@ static void DebugAction_FlagsVars_SwitchPokeNav(u8 taskId); static void DebugAction_FlagsVars_SwitchMatchCall(u8 taskId); static void DebugAction_FlagsVars_ToggleFlyFlags(u8 taskId); static void DebugAction_FlagsVars_ToggleBadgeFlags(u8 taskId); +static void DebugAction_FlagsVars_ToggleGameClear(u8 taskId); static void DebugAction_FlagsVars_ToggleFrontierPass(u8 taskId); static void DebugAction_FlagsVars_CollisionOnOff(u8 taskId); static void DebugAction_FlagsVars_EncounterOnOff(u8 taskId); @@ -577,6 +579,7 @@ static const u8 sDebugText_FlagsVars_SwitchMatchCall[] = _("Toggle {STR_VAR_ static const u8 sDebugText_FlagsVars_RunningShoes[] = _("Toggle {STR_VAR_1}Running Shoes"); static const u8 sDebugText_FlagsVars_ToggleFlyFlags[] = _("Toggle {STR_VAR_1}Fly Flags"); static const u8 sDebugText_FlagsVars_ToggleAllBadges[] = _("Toggle {STR_VAR_1}All badges"); +static const u8 sDebugText_FlagsVars_ToggleGameClear[] = _("Toggle {STR_VAR_1}Game clear"); static const u8 sDebugText_FlagsVars_ToggleFrontierPass[] = _("Toggle {STR_VAR_1}Frontier Pass"); static const u8 sDebugText_FlagsVars_SwitchCollision[] = _("Toggle {STR_VAR_1}Collision OFF"); static const u8 sDebugText_FlagsVars_SwitchEncounter[] = _("Toggle {STR_VAR_1}Encounter OFF"); @@ -787,6 +790,7 @@ static const struct ListMenuItem sDebugMenu_Items_FlagsVars[] = [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES] = {sDebugText_FlagsVars_RunningShoes, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES}, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS] = {sDebugText_FlagsVars_ToggleFlyFlags, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS}, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL] = {sDebugText_FlagsVars_ToggleAllBadges, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL}, + [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR] = {sDebugText_FlagsVars_ToggleGameClear, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR}, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS] = {sDebugText_FlagsVars_ToggleFrontierPass, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS}, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION] = {sDebugText_FlagsVars_SwitchCollision, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION}, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER] = {sDebugText_FlagsVars_SwitchEncounter, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER}, @@ -958,6 +962,7 @@ static void (*const sDebugMenu_Actions_Flags[])(u8) = [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES] = DebugAction_FlagsVars_RunningShoes, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS] = DebugAction_FlagsVars_ToggleFlyFlags, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL] = DebugAction_FlagsVars_ToggleBadgeFlags, + [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR] = DebugAction_FlagsVars_ToggleGameClear, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS] = DebugAction_FlagsVars_ToggleFrontierPass, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION] = DebugAction_FlagsVars_CollisionOnOff, [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER] = DebugAction_FlagsVars_EncounterOnOff, @@ -1308,6 +1313,9 @@ static u8 Debug_CheckToggleFlags(u8 id) FlagGet(FLAG_BADGE07_GET) && FlagGet(FLAG_BADGE08_GET); break; + case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR: + result = FlagGet(FLAG_SYS_GAME_CLEAR); + break; case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS: result = FlagGet(FLAG_SYS_FRONTIER_PASS); break; @@ -2862,6 +2870,16 @@ static void DebugAction_FlagsVars_ToggleBadgeFlags(u8 taskId) } } +static void DebugAction_FlagsVars_ToggleGameClear(u8 taskId) +{ + // Sound effect + if (FlagGet(FLAG_SYS_GAME_CLEAR)) + PlaySE(SE_PC_OFF); + else + PlaySE(SE_PC_LOGIN); + FlagToggle(FLAG_SYS_GAME_CLEAR); +} + static void DebugAction_FlagsVars_ToggleFrontierPass(u8 taskId) { // Sound effect diff --git a/src/dexnav.c b/src/dexnav.c new file mode 100644 index 0000000000..c3d8e3b992 --- /dev/null +++ b/src/dexnav.c @@ -0,0 +1,2688 @@ +#include "global.h" +#include "battle_main.h" +#include "battle_setup.h" +#include "bg.h" +#include "data.h" +#include "daycare.h" +#include "decompress.h" +#include "dexnav.h" +#include "event_data.h" +#include "event_object_movement.h" +#include "event_scripts.h" +#include "field_effect.h" +#include "field_effect_helpers.h" +#include "field_message_box.h" +#include "field_player_avatar.h" +#include "field_screen_effect.h" +#include "fieldmap.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "item.h" +#include "international_string_util.h" +#include "m4a.h" +#include "map_name_popup.h" +#include "main.h" +#include "malloc.h" +#include "menu.h" +#include "menu_helpers.h" +#include "metatile_behavior.h" +#include "move.h" +#include "overworld.h" +#include "palette.h" +#include "party_menu.h" +#include "pokedex.h" +#include "pokemon.h" +#include "pokemon_icon.h" +#include "pokemon_summary_screen.h" +#include "random.h" +#include "region_map.h" +#include "scanline_effect.h" +#include "script.h" +#include "script_pokemon_util.h" +#include "sound.h" +#include "sprite.h" +#include "start_menu.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "wild_encounter.h" +#include "window.h" +#include "constants/map_types.h" +#include "constants/species.h" +#include "constants/maps.h" +#include "constants/field_effects.h" +#include "constants/items.h" +#include "constants/songs.h" +#include "constants/abilities.h" +#include "constants/rgb.h" +#include "constants/region_map_sections.h" +#include "gba/m4a_internal.h" + +#if DEXNAV_ENABLED +STATIC_ASSERT(FLAG_SYS_DEXNAV_SEARCH != 0, FlagSysDexNavSearch_Must_Not_Be_Zero); +STATIC_ASSERT(FLAG_SYS_DETECTOR_MODE != 0, FlagSysDetectorMode_Must_Not_Be_Zero); +STATIC_ASSERT(VAR_DEXNAV_SPECIES != 0, VarDexNavSpecies_Must_Not_Be_Zero); +STATIC_ASSERT(VAR_DEXNAV_STEP_COUNTER != 0, VarDexNavStepCounter_Must_Not_Be_Zero); +#endif + +// Defines +enum WindowIds +{ + WINDOW_INFO, + WINDOW_REGISTERED, + WINDOW_COUNT, +}; + +enum Statuses +{ + STATUS_INVALID_SEARCH, + STATUS_CHOOSE_MON, + STATUS_LOCKED, + STATUS_NO_DATA, + STATUS_INCORRECT_AREA, +}; + +struct DexNavSearch +{ + u16 species; + u16 moves[MAX_MON_MOVES]; + u16 heldItem; + u8 abilityNum; + u8 potential; + u8 searchLevel; + u8 monLevel; + u8 proximity; + u8 environment; + s16 tileX; + s16 tileY; + u8 fldEffSpriteId; + u8 fldEffId; + u8 movementCount; + u8 windowId; + u8 iconSpriteId; + u8 eyeSpriteId; + u8 itemSpriteId; + u8 starSpriteIds[3]; + u8 ownedIconSpriteId; + u8 exclamationSpriteId; + u8 hiddenSearch:1; + u8 isHiddenMon:1; + u8 unk:6; + u16 palBuffer[16]; +}; + +struct DexNavGUI +{ + MainCallback savedCallback; + u8 state; + u8 cursorSpriteId; + u16 landSpecies[LAND_WILD_COUNT]; + u16 waterSpecies[WATER_WILD_COUNT]; + u16 hiddenSpecies[HIDDEN_WILD_COUNT]; + u8 cursorRow; + u8 cursorCol; + u8 environment; + u8 potential; + u8 typeIconSpriteIds[2]; + u8 starSpriteIds[3]; +}; + +// RAM + +EWRAM_DATA static struct DexNavSearch *sDexNavSearchDataPtr = NULL; +EWRAM_DATA static struct DexNavGUI *sDexNavUiDataPtr = NULL; +EWRAM_DATA static u8 *sBg1TilemapBuffer = NULL; +EWRAM_DATA bool8 gDexNavBattle = FALSE; + +//// Function Declarations +//GUI +static void Task_DexNavWaitFadeIn(u8 taskId); +static void Task_DexNavMain(u8 taskId); +static void PrintCurrentSpeciesInfo(void); +// SEARCH +static bool8 TryStartHiddenMonFieldEffect(u8 environment, u8 xSize, u8 ySize, bool8 smallScan); +static void DexNavGenerateMoveset(u16 species, u8 searchLevel, u8 encounterLevel, u16* moveDst); +static u16 DexNavGenerateHeldItem(u16 species, u8 searchLevel); +static u8 DexNavGetAbilityNum(u16 species, u8 searchLevel); +static u8 DexNavGeneratePotential(u8 searchLevel); +static u8 DexNavTryGenerateMonLevel(u16 species, u8 environment); +static u8 GetEncounterLevelFromMapData(u16 species, u8 environment); +static void CreateDexNavWildMon(u16 species, u8 potential, u8 level, u8 abilityNum, u16 item, u16* moves); +static u8 GetPlayerDistance(s16 x, s16 y); +static u8 DexNavPickTile(u8 environment, u8 xSize, u8 ySize, bool8 smallScan); +static void DexNavProximityUpdate(void); +static void DexNavDrawIcons(void); +static void DexNavUpdateSearchWindow(u8 proximity, u8 searchLevel); +static void Task_DexNavSearch(u8 taskId); +static void EndDexNavSearchSetupScript(const u8 *script, u8 taskId); +// HIDDEN MONS +static void DexNavDrawHiddenIcons(void); +static void DrawHiddenSearchWindow(u8 width); + +//// Const Data +// gui image data +static const u32 sDexNavGuiTiles[] = INCBIN_U32("graphics/dexnav/gui_tiles.4bpp.lz"); +static const u32 sDexNavGuiTilemap[] = INCBIN_U32("graphics/dexnav/gui_tilemap.bin.lz"); +static const u32 sDexNavGuiPal[] = INCBIN_U32("graphics/dexnav/gui.gbapal"); + +static const u32 sSelectionCursorGfx[] = INCBIN_U32("graphics/dexnav/cursor.4bpp.lz"); +static const u16 sSelectionCursorPal[] = INCBIN_U16("graphics/dexnav/cursor.gbapal"); +static const u32 sCapturedAllMonsTiles[] = INCBIN_U32("graphics/dexnav/captured_all.4bpp.lz"); //uses selection cursor pal + +static const u32 sNoDataGfx[] = INCBIN_U32("graphics/dexnav/no_data.4bpp.lz"); + +// searching image data +static const u32 sPotentialStarGfx[] = INCBIN_U32("graphics/dexnav/star.4bpp.lz"); +static const u32 sHiddenSearchIconGfx[] = INCBIN_U32("graphics/dexnav/hidden_search.4bpp.lz"); +static const u32 sOwnedIconGfx[] = INCBIN_U32("graphics/dexnav/owned_icon.4bpp.lz"); +static const u32 sHiddenMonIconGfx[] = INCBIN_U32("graphics/dexnav/hidden.4bpp.lz"); + +// strings +static const u8 sText_DexNav_NoInfo[] = _("--------"); +static const u8 sText_DexNav_CaptureToSee[] = _("Capture first!"); +static const u8 sText_DexNav_PressRToRegister[] = _("R TO REGISTER!"); +static const u8 sText_DexNav_SearchForRegisteredSpecies[] = _("Search {STR_VAR_1}"); +static const u8 sText_DexNav_NotFoundHere[] = _("This Pokémon cannot be found here!"); +static const u8 sText_ThreeQmarks[] = _("???"); +static const u8 sText_SearchLevel[] = _("SEARCH {LV}. {STR_VAR_1}"); +static const u8 sText_MonLevel[] = _("{LV}. {STR_VAR_1}"); +static const u8 sText_EggMove[] = _("MOVE: {STR_VAR_1}"); +static const u8 sText_HeldItem[] = _("{STR_VAR_1}"); +static const u8 sText_StartExit[] = _("{START_BUTTON} EXIT"); +static const u8 sText_DexNavChain[] = _("{NO} {STR_VAR_1}"); +static const u8 sText_DexNavChainLong[] = _("{NO}{STR_VAR_1}"); + +static const u8 sText_ArrowLeft[] = _("{LEFT_ARROW}"); +static const u8 sText_ArrowRight[] = _("{RIGHT_ARROW}"); +static const u8 sText_ArrowUp[] = _("{UP_ARROW}"); +static const u8 sText_ArrowDown[] = _("{DOWN_ARROW}"); + +static const struct WindowTemplate sDexNavGuiWindowTemplates[] = +{ + [WINDOW_INFO] = + { + .bg = 0, + .tilemapLeft = 21, + .tilemapTop = 5, + .width = 9, + .height = 15, + .paletteNum = 15, + .baseBlock = 1, + }, + [WINDOW_REGISTERED] = + { + .bg = 0, + .tilemapLeft = 4, + .tilemapTop = 0, + .width = 26, + .height = 2, + .paletteNum = 15, + .baseBlock = 200, + }, + DUMMY_WIN_TEMPLATE +}; + +//gui font +static const u8 sFontColor_Black[3] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY}; +static const u8 sFontColor_White[3] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}; +//search window font +static const u8 sSearchFontColor[3] = {0, 15, 13}; + +static const struct OamData sNoDataIconOam = +{ + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .shape = SPRITE_SHAPE(32x32), + .size = SPRITE_SIZE(32x32), + .priority = 1, +}; + +static const struct OamData sHeldItemOam = +{ + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .shape = SPRITE_SHAPE(8x8), + .size = SPRITE_SIZE(8x8), + .priority = 0, + .paletteNum = 13, +}; + +static const struct OamData sCapturedAllOam = +{ + .y = 0, + .affineMode = 1, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = SPRITE_SHAPE(8x8), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(8x8), + .tileNum = 0, + .priority = 0, //Highest + .paletteNum = 12, + .affineParam = 0, +}; + +static const struct OamData sSearchIconOam = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(32x32), + .tileNum = 0, + .priority = 0, // above BG layers + .paletteNum = 13, + .affineParam = 0 +}; + +static const struct OamData sSelectionCursorOam = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(32x32), + .tileNum = 0, + .priority = 0, // above BG layers + .paletteNum = 12, + .affineParam = 0 +}; + +static const struct OamData sSightOam = +{ + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .shape = SPRITE_SHAPE(16x8), + .size = SPRITE_SIZE(16x8), + .priority = 0, +}; +static const union AnimCmd sAnimCmdSight0[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END +}; +static const union AnimCmd sAnimCmdSight1[] = +{ + ANIMCMD_FRAME(2, 1), + ANIMCMD_END +}; +static const union AnimCmd sAnimCmdSight2[] = +{ + ANIMCMD_FRAME(4, 1), + ANIMCMD_END +}; +static const union AnimCmd *const sAnimCmdTable_Sight[] = +{ + sAnimCmdSight0, + sAnimCmdSight1, + sAnimCmdSight2, +}; + +// gui sprite templates +static const struct SpriteTemplate sNoDataIconTemplate = +{ + .tileTag = ICON_GFX_TAG, + .paletteTag = ICON_PAL_TAG, + .oam = &sNoDataIconOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sCaptureAllMonsSpriteTemplate = +{ + .tileTag = CAPTURED_ALL_TAG, + .paletteTag = 0xFFFF, + .oam = &sCapturedAllOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sSelectionCursorSpriteTemplate = +{ + .tileTag = SELECTION_CURSOR_TAG, + .paletteTag = 0xFFFF, + .oam = &sSelectionCursorOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +// search window sprite templates +static const struct SpriteTemplate sHeldItemTemplate = +{ + .tileTag = HELD_ITEM_TAG, + .paletteTag = 0xFFFF, + .oam = &sHeldItemOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sPotentialStarTemplate = +{ + .tileTag = LIT_STAR_TILE_TAG, + .paletteTag = 0xFFFF, //held item pal + .oam = &sHeldItemOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sSearchIconSpriteTemplate = +{ + .tileTag = HIDDEN_SEARCH_TAG, + .paletteTag = 0xFFFF, //held item pal + .oam = &sSearchIconOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sOwnedIconTemplate = +{ + .tileTag = OWNED_ICON_TAG, + .paletteTag = 0xFFFF, //held item pal + .oam = &sHeldItemOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sHiddenMonIconTemplate = +{ + .tileTag = HIDDEN_MON_ICON_TAG, + .paletteTag = 0xFFFF, //held item pal + .oam = &sHeldItemOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +// gui sprite sheets +static const struct CompressedSpriteSheet sNoDataIconSpriteSheet = {sNoDataGfx, (32 * 32) / 2, ICON_GFX_TAG}; +static const struct CompressedSpriteSheet sCapturedAllPokemonSpriteSheet = {sCapturedAllMonsTiles, (8 * 8) / 2, CAPTURED_ALL_TAG}; +// search sprite sheets +static const struct CompressedSpriteSheet sPotentialStarSpriteSheet = {sPotentialStarGfx, (8 * 8) / 2, LIT_STAR_TILE_TAG}; +static const struct CompressedSpriteSheet sOwnedIconSpriteSheet = {sOwnedIconGfx, (8 * 8) / 2, OWNED_ICON_TAG}; +static const struct CompressedSpriteSheet sHiddenMonIconSpriteSheet = {sHiddenMonIconGfx, (8 * 8) / 2, HIDDEN_MON_ICON_TAG}; + +//// functions +/////////////////////// +//// DEXNAV SEARCH //// +/////////////////////// +static s16 GetSearchWindowY(void) +{ + return (GetWindowAttribute(sDexNavSearchDataPtr->windowId, WINDOW_TILEMAP_TOP) * 8); +} + +#define SPECIES_ICON_X 28 +static void DrawDexNavSearchMonIcon(u16 species, u8 *dst, bool8 owned) +{ + u8 spriteId; + + LoadMonIconPalette(species); + spriteId = CreateMonIcon(species, SpriteCB_MonIcon, SPECIES_ICON_X - 6, GetSearchWindowY() + 8, 0, 0xFFFFFFFF); + gSprites[spriteId].oam.priority = 0; + *dst = spriteId; + + if (owned) + sDexNavSearchDataPtr->ownedIconSpriteId = CreateSprite(&sOwnedIconTemplate, SPECIES_ICON_X + 6, GetSearchWindowY() + 4, 0); +} + +static void AddSearchWindow(u8 width) +{ + struct WindowTemplate template; + u16 y = 16; + + if (sDexNavSearchDataPtr->tileY > (gSaveBlock1Ptr->pos.y + 7)) + y = 1; //draw at top if chosen tile is below + + LoadDexNavWindowGfx(sDexNavSearchDataPtr->windowId, 0x1d5, 14 * 16); + + SetWindowTemplateFields(&template, 0, 1, y, width, 3, 14, 8); + + sDexNavSearchDataPtr->windowId = AddWindow(&template); + FillWindowPixelBuffer(sDexNavSearchDataPtr->windowId, PIXEL_FILL(1)); + PutWindowTilemap(sDexNavSearchDataPtr->windowId); + CopyWindowToVram(sDexNavSearchDataPtr->windowId, 3); + + DrawStdFrameWithCustomTileAndPalette(sDexNavSearchDataPtr->windowId, TRUE, 0x214, 14); +} + +#define WINDOW_COL_0 (SPECIES_ICON_X + 4) +#define WINDOW_COL_1 (WINDOW_COL_0 + (GetFontAttribute(sDexNavSearchDataPtr->windowId, FONTATTR_MAX_LETTER_WIDTH) * (POKEMON_NAME_LENGTH))) +#define WINDOW_MOVE_NAME_X (WINDOW_COL_1 + (GetFontAttribute(sDexNavSearchDataPtr->windowId, FONTATTR_MAX_LETTER_WIDTH) * 6)) +#define SEARCH_ARROW_X (WINDOW_MOVE_NAME_X + 90) +#define SEARCH_ARROW_Y 0 + +static void AddSearchWindowText(u16 species, u8 proximity, u8 searchLevel, bool8 hidden) +{ + u8 windowId = sDexNavSearchDataPtr->windowId; + + //species name - always present + if (hidden) + { + StringCopy(gStringVar4, sText_ThreeQmarks); + AddTextPrinterParameterized3(sDexNavSearchDataPtr->windowId, 0, WINDOW_COL_0, 0, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + return; + } + else + { + StringCopy(gStringVar1, GetSpeciesName(species)); + AddTextPrinterParameterized3(sDexNavSearchDataPtr->windowId, 0, WINDOW_COL_0, 0, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar1); + } + + //level - always present + ConvertIntToDecimalStringN(gStringVar1, sDexNavSearchDataPtr->monLevel, STR_CONV_MODE_LEFT_ALIGN, 3); + StringExpandPlaceholders(gStringVar4, sText_MonLevel); + AddTextPrinterParameterized3(sDexNavSearchDataPtr->windowId, 0, WINDOW_COL_1, 0, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + + if (proximity <= SNEAKING_PROXIMITY) + { + PlaySE(SE_POKENAV_ON); + // move + if (searchLevel > 1 && sDexNavSearchDataPtr->moves[0]) + { + StringCopy(gStringVar1, GetMoveName(sDexNavSearchDataPtr->moves[0])); + StringExpandPlaceholders(gStringVar4, sText_EggMove); + AddTextPrinterParameterized3(windowId, 0, WINDOW_MOVE_NAME_X, 0, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + } + + if (searchLevel > 2) + { + // ability name + StringCopy(gStringVar1, gAbilitiesInfo[GetAbilityBySpecies(species, sDexNavSearchDataPtr->abilityNum)].name); + AddTextPrinterParameterized3(windowId, 0, WINDOW_COL_1 + 16, 12, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar1); + + // item name + if (sDexNavSearchDataPtr->heldItem) + { + CopyItemName(sDexNavSearchDataPtr->heldItem, gStringVar1); + StringExpandPlaceholders(gStringVar4, sText_HeldItem); + AddTextPrinterParameterized3(windowId, 0, WINDOW_COL_0, 12, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + } + } + } + + //chain level - always present + ConvertIntToDecimalStringN(gStringVar1, gSaveBlock3Ptr->dexNavChain, STR_CONV_MODE_LEFT_ALIGN, 3); + if (gSaveBlock3Ptr->dexNavChain > 99) + StringExpandPlaceholders(gStringVar4, sText_DexNavChainLong); + else + StringExpandPlaceholders(gStringVar4, sText_DexNavChain); + AddTextPrinterParameterized3(windowId, 0, SEARCH_ARROW_X - 16, 12, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + + CopyWindowToVram(sDexNavSearchDataPtr->windowId, 2); +} + +#define SEARCH_WINDOW_WIDTH 28 + +static void DrawSearchWindow(u16 species, u8 potential, bool8 hidden) +{ + u8 searchLevel = sDexNavSearchDataPtr->searchLevel; + + AddSearchWindow(SEARCH_WINDOW_WIDTH); + AddSearchWindowText(species, sDexNavSearchDataPtr->proximity, searchLevel, hidden); +} + +#undef SEARCH_WINDOW_WIDTH + +static void RemoveDexNavWindowAndGfx(void) +{ + u32 i; + + // try remove sprites + if (sDexNavSearchDataPtr->iconSpriteId != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->iconSpriteId]); + if (sDexNavSearchDataPtr->itemSpriteId != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->itemSpriteId]); + if (sDexNavSearchDataPtr->eyeSpriteId != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->eyeSpriteId]); + if (sDexNavSearchDataPtr->ownedIconSpriteId != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->ownedIconSpriteId]); + if (sDexNavSearchDataPtr->exclamationSpriteId != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->exclamationSpriteId]); + + for (i = 0; i < NELEMS(sDexNavSearchDataPtr->starSpriteIds); i++) + { + if (sDexNavSearchDataPtr->starSpriteIds[i] != MAX_SPRITES) + DestroySprite(&gSprites[sDexNavSearchDataPtr->starSpriteIds[i]]); + } + + FreeSpriteTilesByTag(HELD_ITEM_TAG); + FreeSpriteTilesByTag(OWNED_ICON_TAG); + FreeSpriteTilesByTag(HIDDEN_SEARCH_TAG); + FreeSpriteTilesByTag(HIDDEN_MON_ICON_TAG); + FreeSpriteTilesByTag(LIT_STAR_TILE_TAG); + FreeSpritePaletteByTag(HELD_ITEM_TAG); + SafeFreeMonIconPalette(sDexNavSearchDataPtr->species); + + // remove window + ClearStdWindowAndFrameToTransparent(sDexNavSearchDataPtr->windowId, FALSE); + CopyWindowToVram(sDexNavSearchDataPtr->windowId, 3); + RemoveWindow(sDexNavSearchDataPtr->windowId); +} + + +////////////////////// +////DEXNAV SEARCH///// +////////////////////// +static u8 GetPlayerDistance(s16 x, s16 y) +{ + u16 deltaX = abs(x - (gSaveBlock1Ptr->pos.x + 7)); + u16 deltaY = abs(y - (gSaveBlock1Ptr->pos.y + 7)); + return deltaX + deltaY; +} + +static void DexNavProximityUpdate(void) +{ + sDexNavSearchDataPtr->proximity = GetPlayerDistance(sDexNavSearchDataPtr->tileX, sDexNavSearchDataPtr->tileY); +} + +//Pick a specific tile based on environment +static bool8 DexNavPickTile(u8 environment, u8 areaX, u8 areaY, bool8 smallScan) +{ + // area of map to cover starting from camera position {-7, -7} + s16 topX = gSaveBlock1Ptr->pos.x - SCANSTART_X + (smallScan * 5); + s16 topY = gSaveBlock1Ptr->pos.y - SCANSTART_Y + (smallScan * 5); + s16 botX = topX + areaX; + s16 botY = topY + areaY; + u8 i; + bool8 nextIter; + u8 scale = 0; + u8 weight = 0; + u8 currMapType = GetCurrentMapType(); + u8 tileBehaviour; + u8 tileBuffer = 2; + u8 *xPos = AllocZeroed((botX - topX) * (botY - topY) * sizeof(u8)); + u8 *yPos = AllocZeroed((botX - topX) * (botY - topY) * sizeof(u8)); + u32 iter = 0; + bool32 ret = FALSE; + + // loop through every tile in area and evaluate + while (topY < botY) + { + while (topX < botX) + { + tileBehaviour = MapGridGetMetatileBehaviorAt(topX, topY); + //Check for objects + nextIter = FALSE; + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_BIKE)) + tileBuffer = SNEAKING_PROXIMITY + 3; + else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) + tileBuffer = SNEAKING_PROXIMITY + 1; + + if (GetPlayerDistance(topX, topY) <= tileBuffer) + { + // tile too close to player + topX++; + continue; + } + + for (i = 0; i < OBJECT_EVENTS_COUNT; i++) + { + if (gObjectEvents[i].currentCoords.x == topX && gObjectEvents[i].currentCoords.y == topY) + { + // cannot be on a tile where an object exists + nextIter = TRUE; + break; + } + } + + if (nextIter) + { + topX++; + continue; + } + + weight = 0; // initiliaze weight + switch (environment) + { + case ENCOUNTER_TYPE_LAND: + if (MetatileBehavior_IsLandWildEncounter(tileBehaviour)) + { + if (currMapType == MAP_TYPE_UNDERGROUND) + { + // inside (cave) + if (IsElevationMismatchAt(gObjectEvents[gPlayerAvatar.spriteId].currentElevation, topX, topY)) + break; //occurs at same z coord + + scale = 440 - (smallScan * 200) - (GetPlayerDistance(topX, topY) / 2) - (2 * (topX + topY)); + weight = ((Random() % scale) < 1) && !MapGridGetCollisionAt(topX, topY); + } + else + { + // outdoors: grass + scale = 100 - (GetPlayerDistance(topX, topY) * 2); + weight = (Random() % scale <= 5) && !MapGridGetCollisionAt(topX, topY); + } + } + break; + case ENCOUNTER_TYPE_WATER: + if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehaviour)) + { + u8 scale = 320 - (smallScan * 200) - (GetPlayerDistance(topX, topY) / 2); + if (IsElevationMismatchAt(gObjectEvents[gPlayerAvatar.spriteId].currentElevation, topX, topY)) + break; + + weight = (Random() % scale <= 1) && !MapGridGetCollisionAt(topX, topY); + } + break; + default: + break; + } + + if (weight > 0) + { + xPos[iter] = topX; + yPos[iter] = topY; + iter++; + } + + topX++; + } + + topY++; + topX = gSaveBlock1Ptr->pos.x - SCANSTART_X + (smallScan * 5); + } + + if (iter > 0) + { + i = Random() % iter; + sDexNavSearchDataPtr->tileX = xPos[i]; + sDexNavSearchDataPtr->tileY = yPos[i]; + ret = TRUE; + } + + Free(xPos); + Free(yPos); + + return ret; +} + + +static bool8 TryStartHiddenMonFieldEffect(u8 environment, u8 xSize, u8 ySize, bool8 smallScan) +{ + u8 currMapType = GetCurrentMapType(); + u8 fldEffId = 0; + + if (DexNavPickTile(environment, xSize, ySize, smallScan)) + { + u8 metatileBehaviour = MapGridGetMetatileBehaviorAt(sDexNavSearchDataPtr->tileX, sDexNavSearchDataPtr->tileY); + + switch (environment) + { + case ENCOUNTER_TYPE_LAND: + if (currMapType == MAP_TYPE_UNDERGROUND) + { + fldEffId = FLDEFF_CAVE_DUST; + } + else if (IsMapTypeIndoors(currMapType)) + { + if (MetatileBehavior_IsTallGrass(metatileBehaviour)) //Grass in cave + fldEffId = FLDEFF_SHAKING_GRASS; + else if (MetatileBehavior_IsLongGrass(metatileBehaviour)) //Really tall grass + fldEffId = FLDEFF_SHAKING_LONG_GRASS; + else if (MetatileBehavior_IsSandOrDeepSand(metatileBehaviour)) + fldEffId = FLDEFF_SAND_HOLE; + else + fldEffId = FLDEFF_CAVE_DUST; + } + else //outdoor, underwater + { + if (MetatileBehavior_IsTallGrass(metatileBehaviour)) //Regular grass + fldEffId = FLDEFF_SHAKING_GRASS; + else if (MetatileBehavior_IsLongGrass(metatileBehaviour)) //Really tall grass + fldEffId = FLDEFF_SHAKING_LONG_GRASS; + else if (MetatileBehavior_IsSandOrDeepSand(metatileBehaviour)) //Desert Sand + fldEffId = FLDEFF_SAND_HOLE; + else if (MetatileBehavior_IsMountain(metatileBehaviour)) //Rough Terrain + fldEffId = FLDEFF_CAVE_DUST; + else + fldEffId = FLDEFF_BERRY_TREE_GROWTH_SPARKLE; //default + } + break; + case ENCOUNTER_TYPE_WATER: + fldEffId = FLDEFF_WATER_SURFACING; + break; + default: + return FALSE; + } + + if (fldEffId != 0) + { + gFieldEffectArguments[0] = sDexNavSearchDataPtr->tileX; + gFieldEffectArguments[1] = sDexNavSearchDataPtr->tileY; + gFieldEffectArguments[2] = 0xFF; // subpriority + gFieldEffectArguments[3] = 2; //priority + sDexNavSearchDataPtr->fldEffSpriteId = FieldEffectStart(fldEffId); + if (sDexNavSearchDataPtr->fldEffSpriteId == MAX_SPRITES) + return FALSE; + + sDexNavSearchDataPtr->fldEffId = fldEffId; + return TRUE; + } + } + + return FALSE; +} + +static void DrawDexNavSearchHeldItem(u8* dst) +{ + *dst = CreateSprite(&sHeldItemTemplate, SPECIES_ICON_X + 6, GetSearchWindowY() + 18, 0); + if (*dst != MAX_SPRITES) + gSprites[*dst].invisible = TRUE; +} + +static void LoadSearchIconData(void) +{ + // palettes clash with mon icon, so must load manually + LoadSpriteSheet(&gSpriteSheet_HeldItem); + LoadPalette(gHeldItemPalette, 0x100 + (16 * sHeldItemOam.paletteNum), 32); + LoadCompressedSpriteSheetUsingHeap(&sPotentialStarSpriteSheet); + //LoadCompressedSpriteSheetUsingHeap(&sSightSpriteSheet); //eye replaced with arrow + LoadCompressedSpriteSheetUsingHeap(&sOwnedIconSpriteSheet); + LoadCompressedSpriteSheetUsingHeap(&sHiddenMonIconSpriteSheet); +} + +static u8 GetSearchLevel(u16 dexNum) +{ + u8 searchLevel; +#if USE_DEXNAV_SEARCH_LEVELS == TRUE + searchLevel = gSaveBlock3Ptr->dexNavSearchLevels[dexNum]; +#else + searchLevel = 0; +#endif + return searchLevel; +} + +#define tProximity data[0] +#define tFrameCount data[1] +#define tSpecies data[2] +#define tEnvironment data[3] +#define tRevealed data[4] + +static void Task_SetUpDexNavSearch(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + u16 species = sDexNavSearchDataPtr->species; + u8 searchLevel = GetSearchLevel(SpeciesToNationalPokedexNum(species)); + + // init sprites + sDexNavSearchDataPtr->iconSpriteId = MAX_SPRITES; + sDexNavSearchDataPtr->itemSpriteId = MAX_SPRITES; + sDexNavSearchDataPtr->eyeSpriteId = MAX_SPRITES; + sDexNavSearchDataPtr->starSpriteIds[0] = MAX_SPRITES; + sDexNavSearchDataPtr->starSpriteIds[1] = MAX_SPRITES; + sDexNavSearchDataPtr->starSpriteIds[2] = MAX_SPRITES; + sDexNavSearchDataPtr->ownedIconSpriteId = MAX_SPRITES; + sDexNavSearchDataPtr->exclamationSpriteId = MAX_SPRITES; + sDexNavSearchDataPtr->searchLevel = searchLevel; + + DexNavGenerateMoveset(species, searchLevel, sDexNavSearchDataPtr->monLevel, &sDexNavSearchDataPtr->moves[0]); + sDexNavSearchDataPtr->heldItem = DexNavGenerateHeldItem(species, searchLevel); + sDexNavSearchDataPtr->abilityNum = DexNavGetAbilityNum(species, searchLevel); + sDexNavSearchDataPtr->potential = DexNavGeneratePotential(searchLevel); + DexNavProximityUpdate(); + + LoadSearchIconData(); + if (sDexNavSearchDataPtr->hiddenSearch) + { + DexNavDrawHiddenIcons(); + } + else + { + DexNavDrawIcons(); + DexNavUpdateSearchWindow(sDexNavSearchDataPtr->proximity, searchLevel); + } + + FlagSet(FLAG_SYS_DEXNAV_SEARCH); + gPlayerAvatar.creeping = TRUE; //initialize as true in case mon appears beside you + task->tProximity = gSprites[gPlayerAvatar.spriteId].x; + task->tFrameCount = 0; + task->func = Task_DexNavSearch; + IncrementGameStat(GAME_STAT_DEXNAV_SCANNED); +} + +static void DexNavSearchBail(u8 taskId, const u8 *script) +{ + TRY_FREE_AND_SET_NULL(sDexNavSearchDataPtr); + FreeMonIconPalettes(); + ScriptContext_SetupScript(script); + DestroyTask(taskId); +} + +static void Task_InitDexNavSearch(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u16 species = task->tSpecies; + u8 environment = task->tEnvironment; + + sDexNavSearchDataPtr = AllocZeroed(sizeof(struct DexNavSearch)); + if (sDexNavSearchDataPtr == NULL) + { + DexNavSearchBail(taskId, EventScript_NotFoundNearby); + return; + } + + // assign non-objects to struct + sDexNavSearchDataPtr->species = species; + sDexNavSearchDataPtr->environment = environment; //updated in DexNavTryGenerateMonLevel if hidden mon + sDexNavSearchDataPtr->isHiddenMon = (environment == ENCOUNTER_TYPE_HIDDEN) ? TRUE : FALSE; + sDexNavSearchDataPtr->monLevel = DexNavTryGenerateMonLevel(species, environment); + + if (GetFlashLevel() > 0) + { + DexNavSearchBail(taskId, EventScript_TooDark); + return; + } + + if (sDexNavSearchDataPtr->monLevel == MON_LEVEL_NONEXISTENT || !TryStartHiddenMonFieldEffect(sDexNavSearchDataPtr->environment, 12, 12, FALSE)) + { + DexNavSearchBail(taskId, EventScript_NotFoundNearby); + return; + } + + sDexNavSearchDataPtr->hiddenSearch = FALSE; + task->tRevealed = TRUE; //search window revealed + task->func = Task_SetUpDexNavSearch; +} + +static void DexNavDrawPotentialStars(u8 potential, u8* dst) +{ + u8 spriteId; + u32 i; + + for (i = 0; i < NELEMS(sDexNavSearchDataPtr->starSpriteIds); i++) + { + spriteId = MAX_SPRITES; + if (potential > i) + spriteId = CreateSprite(&sPotentialStarTemplate, SPECIES_ICON_X - 20, GetSearchWindowY() + 4 + (i * 8), 0); + + dst[i] = spriteId; + if (spriteId != MAX_SPRITES) + gSprites[spriteId].invisible = TRUE; + } +} + +static void DexNavUpdateDirectionArrow(void) +{ + u16 tileX = sDexNavSearchDataPtr->tileX; + u16 tileY = sDexNavSearchDataPtr->tileY; + u16 playerX = gSaveBlock1Ptr->pos.x + 7; + u16 playerY = gSaveBlock1Ptr->pos.y + 7; + u16 deltaX = abs(tileX - playerX); + u16 deltaY = abs(tileY - playerY); + const u8 *str; + u8 windowId = sDexNavSearchDataPtr->windowId; + + FillWindowPixelRect(windowId, PIXEL_FILL(1), SEARCH_ARROW_X, SEARCH_ARROW_Y, 12, 12); + if (deltaX <= 1 && deltaY <= 1) + { + str = gText_EmptyString2; + } + else if (deltaX > deltaY) + { + if (playerX > tileX) + str = sText_ArrowLeft; //player to right + else + str = sText_ArrowRight; //player to left + } + else //greater Y diff + { + if (playerY > tileY) + str = sText_ArrowUp; //player below + else + str = sText_ArrowDown; //player above + } + + AddTextPrinterParameterized3(windowId, 1, SEARCH_ARROW_X, SEARCH_ARROW_Y, sSearchFontColor, TEXT_SKIP_DRAW, str); + CopyWindowToVram(windowId, 2); +} + +static void DexNavDrawIcons(void) +{ + u16 species = sDexNavSearchDataPtr->species; + + DrawSearchWindow(species, sDexNavSearchDataPtr->potential, FALSE); + DrawDexNavSearchMonIcon(species, &sDexNavSearchDataPtr->iconSpriteId, GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)); + DrawDexNavSearchHeldItem(&sDexNavSearchDataPtr->itemSpriteId); + DexNavDrawPotentialStars(sDexNavSearchDataPtr->potential, &sDexNavSearchDataPtr->starSpriteIds[0]); + DexNavUpdateDirectionArrow(); +} + +///////////////////// +//// SEARCH TASK //// +///////////////////// +bool8 TryStartDexNavSearch(void) +{ + u8 taskId; + u16 val = VarGet(VAR_DEXNAV_SPECIES); + + if (FlagGet(FLAG_SYS_DEXNAV_SEARCH) || (val & DEXNAV_MASK_SPECIES) == SPECIES_NONE) + return FALSE; + + HideMapNamePopUpWindow(); + ChangeBgY_ScreenOff(0, 0, 0); + taskId = CreateTask(Task_InitDexNavSearch, 0); + gTasks[taskId].tSpecies = val & DEXNAV_MASK_SPECIES; + gTasks[taskId].tEnvironment = val >> 14; + PlaySE(SE_DEX_SEARCH); + return FALSE; //we dont actually want to enable the script context +} + +void EndDexNavSearch(u8 taskId) +{ + FlagClear(FLAG_SYS_DEXNAV_SEARCH); + DestroyTask(taskId); + RemoveDexNavWindowAndGfx(); + FieldEffectStop(&gSprites[sDexNavSearchDataPtr->fldEffSpriteId], sDexNavSearchDataPtr->fldEffId); + Free(sDexNavSearchDataPtr); +} + +static void EndDexNavSearchSetupScript(const u8 *script, u8 taskId) +{ + gSaveBlock3Ptr->dexNavChain = 0; //reset chain + EndDexNavSearch(taskId); + ScriptContext_SetupScript(script); +} + +static u8 GetMovementProximityBySearchLevel(void) +{ + if (sDexNavSearchDataPtr->searchLevel < 20) + return 2; + else if (sDexNavSearchDataPtr->searchLevel < 50) + return 3; + else + return 4; +} + +static void Task_RevealHiddenMon(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u16 species = sDexNavSearchDataPtr->species; + + // remove owned icon if it exists + if (sDexNavSearchDataPtr->ownedIconSpriteId != MAX_SPRITES) + { + DestroySprite(&gSprites[sDexNavSearchDataPtr->ownedIconSpriteId]); + sDexNavSearchDataPtr->ownedIconSpriteId = MAX_SPRITES; + } + + // remove exclamation if it exists + if (sDexNavSearchDataPtr->exclamationSpriteId != MAX_SPRITES) + { + DestroySprite(&gSprites[sDexNavSearchDataPtr->exclamationSpriteId]); + sDexNavSearchDataPtr->exclamationSpriteId = MAX_SPRITES; + } + + + if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN)) + { + u8 index; + + //if not seen, hide name and whiteout mon + DrawSearchWindow(species, sDexNavSearchDataPtr->potential, TRUE); + DrawDexNavSearchMonIcon(species, &sDexNavSearchDataPtr->iconSpriteId, FALSE); + // whiteout icon + index = IndexOfSpritePaletteTag(gSprites[sDexNavSearchDataPtr->iconSpriteId].template->paletteTag); + CpuCopy16(&gPlttBufferUnfaded[0x100 + index * 16], sDexNavSearchDataPtr->palBuffer, 32); + TintPalette_CustomTone(sDexNavSearchDataPtr->palBuffer, 16, 510, 510, 510); + LoadPalette(sDexNavSearchDataPtr->palBuffer, 0x100 + index * 16, 32); + } + else + { + DrawSearchWindow(species, sDexNavSearchDataPtr->potential, FALSE); + DrawDexNavSearchMonIcon(species, &sDexNavSearchDataPtr->iconSpriteId, GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)); + } + + DexNavUpdateDirectionArrow(); + task->func = Task_DexNavSearch; + task->tFrameCount = 0; //restart search clock +} + +static void Task_DexNavSearch(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (sDexNavSearchDataPtr->proximity > MAX_PROXIMITY) + { // out of range + if (sDexNavSearchDataPtr->hiddenSearch && !task->tRevealed) + EndDexNavSearch(taskId); + else + EndDexNavSearchSetupScript(EventScript_LostSignal, taskId); + return; + } + + if (sDexNavSearchDataPtr->proximity <= CREEPING_PROXIMITY && !gPlayerAvatar.creeping && task->tFrameCount > 60) + { //should be creeping but player walks normally + if (sDexNavSearchDataPtr->hiddenSearch && !task->tRevealed) + EndDexNavSearch(taskId); + else + EndDexNavSearchSetupScript(EventScript_MovedTooFast, taskId); + return; + } + + if (sDexNavSearchDataPtr->proximity <= SNEAKING_PROXIMITY && TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH | PLAYER_AVATAR_FLAG_BIKE)) + { // running/biking too close + //always do event script, even if player hasn't revealed a hidden mon. It's assumed they would be creeping towards it + EndDexNavSearchSetupScript(EventScript_MovedTooFast, taskId); + return; + } + + if (ArePlayerFieldControlsLocked() == TRUE) + { // check if script just executed + EndDexNavSearch(taskId); + return; + } + + if (gTasks[taskId].tFrameCount > DEXNAV_TIMEOUT * 60) + { // player took too long + if (sDexNavSearchDataPtr->hiddenSearch && !task->tRevealed) + EndDexNavSearch(taskId); + else + EndDexNavSearchSetupScript(EventScript_PokemonGotAway, taskId); + return; + } + + if (sDexNavSearchDataPtr->proximity < 1) + { + gDexNavBattle = TRUE; + CreateDexNavWildMon(sDexNavSearchDataPtr->species, sDexNavSearchDataPtr->potential, sDexNavSearchDataPtr->monLevel, + sDexNavSearchDataPtr->abilityNum, sDexNavSearchDataPtr->heldItem, sDexNavSearchDataPtr->moves); + + FlagClear(FLAG_SYS_DEXNAV_SEARCH); + ScriptContext_SetupScript(EventScript_StartDexNavBattle); + Free(sDexNavSearchDataPtr); + DestroyTask(taskId); + return; + } + + if (sDexNavSearchDataPtr->hiddenSearch && !task->tRevealed && + (JOY_NEW(R_BUTTON) || (sDexNavSearchDataPtr->proximity < CREEPING_PROXIMITY))) + { + PlaySE(SE_DEX_SEARCH); + ClearStdWindowAndFrameToTransparent(sDexNavSearchDataPtr->windowId, FALSE); + CopyWindowToVram(sDexNavSearchDataPtr->windowId, 3); + RemoveWindow(sDexNavSearchDataPtr->windowId); + DestroySprite(&gSprites[sDexNavSearchDataPtr->iconSpriteId]); + task->tRevealed = TRUE; //regular dexnav search + //sDexNavSearchDataPtr->hiddenSearch = FALSE; //now its a regular dexnav search + task->func = Task_RevealHiddenMon; + return; + } + + //Caves and water the pokemon moves around + if ((sDexNavSearchDataPtr->environment == ENCOUNTER_TYPE_WATER || GetCurrentMapType() == MAP_TYPE_UNDERGROUND) + && sDexNavSearchDataPtr->proximity < GetMovementProximityBySearchLevel() && sDexNavSearchDataPtr->movementCount < 2 + && task->tRevealed) + { + FieldEffectStop(&gSprites[sDexNavSearchDataPtr->fldEffSpriteId], sDexNavSearchDataPtr->fldEffId); + + if (!TryStartHiddenMonFieldEffect(sDexNavSearchDataPtr->environment, 10, 10, TRUE)) + { + EndDexNavSearchSetupScript(EventScript_PokemonGotAway, taskId); + return; + } + + sDexNavSearchDataPtr->movementCount++; + } + + DexNavProximityUpdate(); + if (task->tProximity != sDexNavSearchDataPtr->proximity) + { + //player has moved + if (task->tRevealed) //update search window info only if hidden mon has been revealed (always true for search mode) + DexNavUpdateSearchWindow(sDexNavSearchDataPtr->proximity, sDexNavSearchDataPtr->searchLevel); + + task->tProximity = sDexNavSearchDataPtr->proximity; + } + + task->tFrameCount++; +} + +static void DexNavUpdateSearchWindow(u8 proximity, u8 searchLevel) +{ + bool8 hideName = FALSE; + + if (sDexNavSearchDataPtr->hiddenSearch && !GetSetPokedexFlag(SpeciesToNationalPokedexNum(sDexNavSearchDataPtr->species), FLAG_GET_SEEN)) + hideName = TRUE; //if a detector mode hidden search and player hasn't seen the mon, hide info + + FillWindowPixelBuffer(sDexNavSearchDataPtr->windowId, PIXEL_FILL(1)); //clear window + AddSearchWindowText(sDexNavSearchDataPtr->species, proximity, searchLevel, hideName); + + DexNavUpdateDirectionArrow(); + + //init hidden sprites + if (sDexNavSearchDataPtr->itemSpriteId != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->itemSpriteId].invisible = TRUE; + if (sDexNavSearchDataPtr->starSpriteIds[0] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[0]].invisible = TRUE; + if (sDexNavSearchDataPtr->starSpriteIds[1] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[1]].invisible = TRUE; + if (sDexNavSearchDataPtr->starSpriteIds[2] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[2]].invisible = TRUE; + + if (proximity <= SNEAKING_PROXIMITY) + { + if (searchLevel > 2 && sDexNavSearchDataPtr->heldItem) + { + // toggle item view + if (sDexNavSearchDataPtr->itemSpriteId != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->itemSpriteId].invisible = FALSE; + } + + if (searchLevel > 4) + { + if (sDexNavSearchDataPtr->starSpriteIds[0] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[0]].invisible = FALSE; + + if (sDexNavSearchDataPtr->starSpriteIds[1] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[1]].invisible = FALSE; + + if (sDexNavSearchDataPtr->starSpriteIds[2] != MAX_SPRITES) + gSprites[sDexNavSearchDataPtr->starSpriteIds[2]].invisible = FALSE; + } + } +} + +////////////////////////////// +//// DEXNAV MON GENERATOR //// +////////////////////////////// +static void CreateDexNavWildMon(u16 species, u8 potential, u8 level, u8 abilityNum, u16 item, u16* moves) +{ + struct Pokemon* mon = &gEnemyParty[0]; + u8 iv[3] = {NUM_STATS}; + u8 i; + u8 perfectIv = 31; + + CreateWildMon(species, level); // shiny rate bonus handled in CreateBoxMon + + // Pick random, unique IVs to set to 31. The number of perfect IVs that are assigned is equal to the potential + iv[0] = Random() % NUM_STATS; // choose 1st perfect stat + do { + iv[1] = Random() % NUM_STATS; + iv[2] = Random() % NUM_STATS; + } while ((iv[1] == iv[0]) // unique 2nd perfect stat + || (iv[2] == iv[0] || iv[2] == iv[1])); // unique 3rd perfect stat + + if (potential > 2 && iv[2] != NUM_STATS) + SetMonData(mon, MON_DATA_HP_IV + iv[2], &perfectIv); + if (potential > 1 && iv[1] != NUM_STATS) + SetMonData(mon, MON_DATA_HP_IV + iv[1], &perfectIv); + if (potential > 0 && iv[0] != NUM_STATS) + SetMonData(mon, MON_DATA_HP_IV + iv[0], &perfectIv); + + //Set ability + SetMonData(mon, MON_DATA_ABILITY_NUM, &abilityNum); + + // Set Held Item + if (item) + SetMonData(mon, MON_DATA_HELD_ITEM, &item); + + //Set moves + for (i = 0; i < MAX_MON_MOVES; i++) + SetMonMoveSlot(mon, moves[i], i); + + CalculateMonStats(mon); +} + +// gets a random level of the species based on map data. +//if it was a hidden encounter, updates the environment it is to be found from the wildheader encounterRate +static u8 DexNavTryGenerateMonLevel(u16 species, u8 environment) +{ + u8 levelBase = GetEncounterLevelFromMapData(species, environment); + u8 levelBonus = gSaveBlock3Ptr->dexNavChain / 5; + + if (levelBase == MON_LEVEL_NONEXISTENT) + return MON_LEVEL_NONEXISTENT; //species not found in the area + + if (Random() % 100 < 4) + levelBonus += 10; //4% chance of having a +10 level + + if (levelBase + levelBonus > MAX_LEVEL) + return MAX_LEVEL; + else + return levelBase + levelBonus; +} + +static void DexNavGenerateMoveset(u16 species, u8 searchLevel, u8 encounterLevel, u16* moveDst) +{ + bool8 genMove = FALSE; + u16 randVal = Random() % 100; + u16 i; + u16 eggMoveBuffer[EGG_MOVES_ARRAY_COUNT]; + + // see if first move slot should be an egg move + if (searchLevel < 5) + { + if (SEARCHLEVEL0_MOVECHANCE != 0 && randVal < SEARCHLEVEL0_MOVECHANCE) + genMove = TRUE; + } + else if (searchLevel < 10) + { + if (SEARCHLEVEL5_MOVECHANCE != 0 && randVal < SEARCHLEVEL5_MOVECHANCE) + genMove = TRUE; + } + else if (searchLevel < 25) + { + if (SEARCHLEVEL10_MOVECHANCE != 0 && randVal < SEARCHLEVEL10_MOVECHANCE) + genMove = TRUE; + } + else if (searchLevel < 50) + { + if (SEARCHLEVEL25_MOVECHANCE != 0 && randVal < SEARCHLEVEL25_MOVECHANCE) + genMove = TRUE; + } + else if (searchLevel < 100) + { + if (SEARCHLEVEL50_MOVECHANCE != 0 && randVal < SEARCHLEVEL50_MOVECHANCE) + genMove = TRUE; + } + else + { + if (SEARCHLEVEL100_MOVECHANCE != 0 && randVal < SEARCHLEVEL100_MOVECHANCE) + genMove = TRUE; + } + + // Generate a wild mon just to get the initial moveset (later overwritten by CreateDexNavWildMon) + CreateWildMon(species, encounterLevel); + + // Store generated mon moves into Dex Nav Struct + for (i = 0; i < MAX_MON_MOVES; i++) + moveDst[i] = GetMonData(&gEnemyParty[0], MON_DATA_MOVE1 + i, NULL); + + // set first move slot to a random egg move if search level is good enough + if (genMove) + { + u8 numEggMoves = GetEggMoves(&gEnemyParty[0], eggMoveBuffer); + if (numEggMoves != 0) + moveDst[0] = eggMoveBuffer[Random() % numEggMoves]; + } +} + +static u16 DexNavGenerateHeldItem(u16 species, u8 searchLevel) +{ + u16 randVal = Random() % 100; + u8 searchLevelInfluence = searchLevel >> 1; + u16 item1 = gSpeciesInfo[species].itemCommon; + u16 item2 = gSpeciesInfo[species].itemRare; + + // if both are the same, 100% to hold + if (item1 == item2) + return item1; + + // if no items can be held, then yeah...no items + if (item2 == ITEM_NONE && item1 == ITEM_NONE) + return ITEM_NONE; + + // if only one entry, 50% chance + if (item2 == ITEM_NONE && item1 != ITEM_NONE) + return (randVal < 50) ? item1 : ITEM_NONE; + + // if both are distinct item1 = 50% + srclvl/2; item2 = 5% + srchlvl/2 + if (randVal < (50 + searchLevelInfluence + 5 + searchLevel)) + return (randVal > 5 + searchLevelInfluence) ? item1 : item2; + else + return ITEM_NONE; + + return ITEM_NONE; +} + +static u8 DexNavGetAbilityNum(u16 species, u8 searchLevel) +{ + bool8 genAbility = FALSE; + u16 randVal = Random() % 100; + u8 abilityNum = 0; + + if (searchLevel < 5) + { + #if (SEARCHLEVEL0_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL0_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + else if (searchLevel < 10) + { + #if (SEARCHLEVEL5_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL5_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + else if (searchLevel < 25) + { + #if (SEARCHLEVEL10_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL10_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + else if (searchLevel < 50) + { + #if (SEARCHLEVEL25_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL25_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + else if (searchLevel < 100) + { + #if (SEARCHLEVEL50_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL50_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + else + { + #if (SEARCHLEVEL100_ABILITYCHANCE != 0) + if (randVal < SEARCHLEVEL100_ABILITYCHANCE) + genAbility = TRUE; + #endif + } + + if (genAbility + && gSpeciesInfo[species].abilities[2] != ABILITY_NONE + && GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + { + //Only give hidden ability if Pokemon has been caught before + abilityNum = 2; + } + else + { + //Pick a normal ability of that Pokemon + if (gSpeciesInfo[species].abilities[1] != ABILITY_NONE) + abilityNum = Random() & 1; + else + abilityNum = 0; + } + + return abilityNum; +} + +static u8 DexNavGeneratePotential(u8 searchLevel) +{ + u8 genChance = 0; + int randVal = Random() % 100; + + if (searchLevel < 5) + { + genChance = SEARCHLEVEL0_ONESTAR + SEARCHLEVEL0_TWOSTAR + SEARCHLEVEL0_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL0_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL0_ONESTAR + SEARCHLEVEL0_TWOSTAR)) + return 2; + else + return 3; + } + } + else if (searchLevel < 10) + { + genChance = SEARCHLEVEL5_ONESTAR + SEARCHLEVEL5_TWOSTAR + SEARCHLEVEL5_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL5_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL5_ONESTAR + SEARCHLEVEL5_TWOSTAR)) + return 2; + else + return 3; + } + } + else if (searchLevel < 25) + { + genChance = SEARCHLEVEL10_ONESTAR + SEARCHLEVEL10_TWOSTAR + SEARCHLEVEL10_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL10_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL10_ONESTAR + SEARCHLEVEL10_TWOSTAR)) + return 2; + else + return 3; + } + } + else if (searchLevel < 50) + { + genChance = SEARCHLEVEL25_ONESTAR + SEARCHLEVEL25_TWOSTAR + SEARCHLEVEL25_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL25_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL25_ONESTAR + SEARCHLEVEL25_TWOSTAR)) + return 2; + else + return 3; + } + } + else if (searchLevel < 100) + { + genChance = SEARCHLEVEL50_ONESTAR + SEARCHLEVEL50_TWOSTAR + SEARCHLEVEL50_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL50_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL50_ONESTAR + SEARCHLEVEL50_TWOSTAR)) + return 2; + else + return 3; + } + } + else + { + genChance = SEARCHLEVEL100_ONESTAR + SEARCHLEVEL100_TWOSTAR + SEARCHLEVEL100_THREESTAR; + if (randVal < genChance) + { + // figure out which star it is + if (randVal < SEARCHLEVEL100_ONESTAR) + return 1; + else if (randVal < (SEARCHLEVEL100_ONESTAR + SEARCHLEVEL100_TWOSTAR)) + return 2; + else + return 3; + } + } + + return 0; // No potential +} + +static u8 GetEncounterLevelFromMapData(u16 species, u8 environment) +{ + u16 headerId = GetCurrentMapWildMonHeaderId(); + const struct WildPokemonInfo *landMonsInfo = gWildMonHeaders[headerId].landMonsInfo; + const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo; + const struct WildPokemonInfo *hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo; + u8 min = 100; + u8 max = 0; + u8 i; + + switch (environment) + { + case ENCOUNTER_TYPE_LAND: // grass + if (landMonsInfo == NULL) + return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles + + for (i = 0; i < LAND_WILD_COUNT; i++) + { + if (landMonsInfo->wildPokemon[i].species == species) + { + min = (min < landMonsInfo->wildPokemon[i].minLevel) ? min : landMonsInfo->wildPokemon[i].minLevel; + max = (max > landMonsInfo->wildPokemon[i].maxLevel) ? max : landMonsInfo->wildPokemon[i].maxLevel; + } + } + break; + case ENCOUNTER_TYPE_WATER: //water + if (waterMonsInfo == NULL) + return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles + + for (i = 0; i < WATER_WILD_COUNT; i++) + { + if (waterMonsInfo->wildPokemon[i].species == species) + { + min = (min < waterMonsInfo->wildPokemon[i].minLevel) ? min : waterMonsInfo->wildPokemon[i].minLevel; + max = (max > waterMonsInfo->wildPokemon[i].maxLevel) ? max : waterMonsInfo->wildPokemon[i].maxLevel; + } + } + break; + case ENCOUNTER_TYPE_HIDDEN: + if (hiddenMonsInfo == NULL) + return MON_LEVEL_NONEXISTENT; + + for (i = 0; i < HIDDEN_WILD_COUNT; i++) + { + if (hiddenMonsInfo->wildPokemon[i].species == species) + { + min = (min < hiddenMonsInfo->wildPokemon[i].minLevel) ? min : hiddenMonsInfo->wildPokemon[i].minLevel; + max = (max > hiddenMonsInfo->wildPokemon[i].maxLevel) ? max : hiddenMonsInfo->wildPokemon[i].maxLevel; + } + } + + // use encounter rate to signify is hidden pokemon are on land or in water + if (hiddenMonsInfo->encounterRate == 1) + sDexNavSearchDataPtr->environment = ENCOUNTER_TYPE_WATER; + else + sDexNavSearchDataPtr->environment = ENCOUNTER_TYPE_LAND; + break; + default: + return MON_LEVEL_NONEXISTENT; + } + + if (max == 0) + return MON_LEVEL_NONEXISTENT; + + return RandomUniform(RNG_DEXNAV_ENCOUNTER_LEVEL, min, max); +} + + +/////////// +/// GUI /// +/////////// +static const struct BgTemplate sDexNavMenuBgTemplates[2] = +{ + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .priority = 0 + }, + { + .bg = 1, + .charBaseIndex = 3, + .mapBaseIndex = 30, + .priority = 1 + } +}; + +static void DexNav_VBlankCB(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void DexNav_MainCB(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + DoScheduledBgTilemapCopiesToVram(); + UpdatePaletteFade(); +} + +static bool8 DexNav_InitBgs(void) +{ + ResetVramOamAndBgCntRegs(); + ResetAllBgsCoordinates(); + sBg1TilemapBuffer = Alloc(0x800); + if (sBg1TilemapBuffer == NULL) + return FALSE; + + memset(sBg1TilemapBuffer, 0, 0x800); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sDexNavMenuBgTemplates, NELEMS(sDexNavMenuBgTemplates)); + SetBgTilemapBuffer(1, sBg1TilemapBuffer); + ScheduleBgCopyTilemapToVram(1); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + SetGpuReg(REG_OFFSET_BLDCNT , 0); + ShowBg(0); + ShowBg(1); + return TRUE; +} + +static bool8 DexNav_LoadGraphics(void) +{ + switch (sDexNavUiDataPtr->state) + { + case 0: + ResetTempTileDataBuffers(); + DecompressAndCopyTileDataToVram(1, sDexNavGuiTiles, 0, 0, 0); + sDexNavUiDataPtr->state++; + break; + case 1: + if (FreeTempTileDataBuffersIfPossible() != TRUE) + { + LZDecompressWram(sDexNavGuiTilemap, sBg1TilemapBuffer); + sDexNavUiDataPtr->state++; + } + break; + case 2: + LoadPalette(sDexNavGuiPal, 0, 32); + sDexNavUiDataPtr->state++; + break; + default: + sDexNavUiDataPtr->state = 0; + return TRUE; + } + + return FALSE; +} + +static void UpdateCursorPosition(void) +{ + u16 x, y; + + switch (sDexNavUiDataPtr->cursorRow) + { + case ROW_WATER: + x = ROW_WATER_ICON_X + (24 * sDexNavUiDataPtr->cursorCol); + y = ROW_WATER_ICON_Y; + sDexNavUiDataPtr->environment = ENCOUNTER_TYPE_WATER; + break; + case ROW_LAND_TOP: //land 1 + x = ROW_LAND_ICON_X + (24 * sDexNavUiDataPtr->cursorCol); + y = ROW_LAND_TOP_ICON_Y; + sDexNavUiDataPtr->environment = ENCOUNTER_TYPE_LAND; + break; + case ROW_LAND_BOT: //land 2 + x = ROW_LAND_ICON_X + (24 * sDexNavUiDataPtr->cursorCol); + y = ROW_LAND_BOT_ICON_Y; + sDexNavUiDataPtr->environment = ENCOUNTER_TYPE_LAND; + break; + case ROW_HIDDEN: + x = ROW_HIDDEN_ICON_X + (24 * sDexNavUiDataPtr->cursorCol); + y = ROW_HIDDEN_ICON_Y; + sDexNavUiDataPtr->environment = ENCOUNTER_TYPE_HIDDEN; + break; + default: + return; + } + + gSprites[sDexNavUiDataPtr->cursorSpriteId].x = x; + gSprites[sDexNavUiDataPtr->cursorSpriteId].y = y; + + PrintCurrentSpeciesInfo(); +} + +static void CreateSelectionCursor(void) +{ + u8 spriteId; + struct CompressedSpriteSheet spriteSheet; + + spriteSheet.data = sSelectionCursorGfx; + spriteSheet.size = 0x200; + spriteSheet.tag = SELECTION_CURSOR_TAG; + LoadCompressedSpriteSheet(&spriteSheet); + + LoadPalette(sSelectionCursorPal, (16 * sSelectionCursorOam.paletteNum) + 0x100, 32); + + spriteId = CreateSprite(&sSelectionCursorSpriteTemplate, 12, 32, 0); + //gSprites[spriteId].data[1] = -1; + + sDexNavUiDataPtr->cursorSpriteId = spriteId; + UpdateCursorPosition(); +} + +static void CreateNoDataIcon(s16 x, s16 y) +{ + CreateSprite(&sNoDataIconTemplate, x, y, 0); +} + +static bool8 CapturedAllLandMons(u16 headerId) +{ + u16 i, species; + int count = 0; + const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo; + + if (landMonsInfo != NULL) + { + for (i = 0; i < LAND_WILD_COUNT; ++i) + { + species = landMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE) + { + if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + break; + + count++; + } + } + + if (i >= LAND_WILD_COUNT && count > 0) //All land mons caught + return TRUE; + } + else + { + return TRUE; //technically, no mon data means you caught them all + } + + return FALSE; +} + +//Checks if all Pokemon that can be encountered while surfing have been capture +static bool8 CapturedAllWaterMons(u16 headerId) +{ + u32 i; + u16 species; + u8 count = 0; + const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo; + + if (waterMonsInfo != NULL) + { + for (i = 0; i < WATER_WILD_COUNT; ++i) + { + species = waterMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE) + { + count++; + if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + break; + } + } + + if (i >= WATER_WILD_COUNT && count > 0) + return TRUE; + } + else + { + return TRUE; //technically, no mon data means you caught them all + } + + return FALSE; +} + +static bool8 CapturedAllHiddenMons(u16 headerId) +{ + u32 i; + u16 species; + u8 count = 0; + const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo; + + if (hiddenMonsInfo != NULL) + { + for (i = 0; i < HIDDEN_WILD_COUNT; ++i) + { + species = hiddenMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE) + { + count++; + if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + break; + } + } + + if (i >= HIDDEN_WILD_COUNT && count > 0) + return TRUE; + } + else + { + return TRUE; //technically, no mon data means you caught them all + } + + return FALSE; +} + +static void DexNavLoadCapturedAllSymbols(void) +{ + u16 headerId = GetCurrentMapWildMonHeaderId(); + + LoadCompressedSpriteSheetUsingHeap(&sCapturedAllPokemonSpriteSheet); + + if (CapturedAllLandMons(headerId)) + CreateSprite(&sCaptureAllMonsSpriteTemplate, 152, 58, 0); + + if (CapturedAllWaterMons(headerId)) + CreateSprite(&sCaptureAllMonsSpriteTemplate, 139, 17, 0); + + if (CapturedAllHiddenMons(headerId)) + CreateSprite(&sCaptureAllMonsSpriteTemplate, 114, 123, 0); +} + +//#define WIN_DETAILS_TILE 0x3a3 +static void DexNav_InitWindows(void) +{ + InitWindows(sDexNavGuiWindowTemplates); + DeactivateAllTextPrinters(); + ScheduleBgCopyTilemapToVram(0); +} + +static void DexNavGuiFreeResources(void) +{ + Free(sDexNavUiDataPtr); + Free(sBg1TilemapBuffer); + FreeAllWindowBuffers(); +} + +static void CB1_InitDexNavSearch(void) +{ + u8 taskId; + + if (!gPaletteFade.active && !ArePlayerFieldControlsLocked() && gMain.callback2 == CB2_Overworld) + { + SetMainCallback1(CB1_Overworld); + taskId = CreateTask(Task_InitDexNavSearch, 0); + gTasks[taskId].tSpecies = gSpecialVar_0x8000; + gTasks[taskId].tEnvironment = gSpecialVar_0x8001; + } +} + +static void CB1_DexNavSearchCallback(void) +{ + CB1_InitDexNavSearch(); +} + +static void Task_DexNavExitAndSearch(u8 taskId) +{ + DexNavGuiFreeResources(); + DestroyTask(taskId); + SetMainCallback1(CB1_DexNavSearchCallback); + SetMainCallback2(CB2_ReturnToField); +} + +static void Task_DexNavFadeAndExit(u8 taskId) +{ + if (!gPaletteFade.active) + { + SetMainCallback2(sDexNavUiDataPtr->savedCallback); + DexNavGuiFreeResources(); + DestroyTask(taskId); + } +} + +static void DexNavFadeAndExit(void) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + CreateTask(Task_DexNavFadeAndExit, 0); + SetVBlankCallback(DexNav_VBlankCB); + SetMainCallback2(DexNav_MainCB); +} + +static bool8 SpeciesInArray(u16 species, u8 section) +{ + u32 i; + u16 dexNum = SpeciesToNationalPokedexNum(species); + + switch (section) + { + case 0: //land + for (i = 0; i < LAND_WILD_COUNT; i++) + { + if (SpeciesToNationalPokedexNum(sDexNavUiDataPtr->landSpecies[i]) == dexNum) + return TRUE; + } + break; + case 1: //water + for (i = 0; i < WATER_WILD_COUNT; i++) + { + if (SpeciesToNationalPokedexNum(sDexNavUiDataPtr->waterSpecies[i]) == dexNum) + return TRUE; + } + break; + case 2: //hidden + for (i = 0; i < HIDDEN_WILD_COUNT; i++) + { + if (SpeciesToNationalPokedexNum(sDexNavUiDataPtr->hiddenSpecies[i]) == dexNum) + return TRUE; + } + break; + default: + break; + } + + return FALSE; +} + +// get unique wild encounters on current map +static void DexNavLoadEncounterData(void) +{ + u8 grassIndex = 0; + u8 waterIndex = 0; + u8 hiddenIndex = 0; + u16 species; + u32 i; + u16 headerId = GetCurrentMapWildMonHeaderId(); + const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo; + const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo; + const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo; + + // nop struct data + memset(sDexNavUiDataPtr->landSpecies, 0, sizeof(sDexNavUiDataPtr->landSpecies)); + memset(sDexNavUiDataPtr->waterSpecies, 0, sizeof(sDexNavUiDataPtr->waterSpecies)); + memset(sDexNavUiDataPtr->hiddenSpecies, 0, sizeof(sDexNavUiDataPtr->hiddenSpecies)); + + // land mons + if (landMonsInfo != NULL && landMonsInfo->encounterRate != 0) + { + for (i = 0; i < LAND_WILD_COUNT; i++) + { + species = landMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE && !SpeciesInArray(species, 0)) + sDexNavUiDataPtr->landSpecies[grassIndex++] = landMonsInfo->wildPokemon[i].species; + } + } + + // water mons + if (waterMonsInfo != NULL && waterMonsInfo->encounterRate != 0) + { + for (i = 0; i < WATER_WILD_COUNT; i++) + { + species = waterMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE && !SpeciesInArray(species, 1)) + sDexNavUiDataPtr->waterSpecies[waterIndex++] = waterMonsInfo->wildPokemon[i].species; + } + } + + // hidden mons + if (hiddenMonsInfo != NULL) // no encounter rate check since 0 means land, 1 means water encounters + { + for (i = 0; i < HIDDEN_WILD_COUNT; i++) + { + species = hiddenMonsInfo->wildPokemon[i].species; + if (species != SPECIES_NONE && !SpeciesInArray(species, 2)) + sDexNavUiDataPtr->hiddenSpecies[hiddenIndex++] = hiddenMonsInfo->wildPokemon[i].species; + } + } +} + +static void TryDrawIconInSlot(u16 species, s16 x, s16 y) +{ + if (species == SPECIES_NONE || species > NUM_SPECIES) + CreateNoDataIcon(x, y); //'X' in slot + else if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN)) + CreateMonIcon(SPECIES_NONE, SpriteCB_MonIcon, x, y, 0, 0xFFFFFFFF); //question mark + else + CreateMonIcon(species, SpriteCB_MonIcon, x, y, 0, 0xFFFFFFFF); +} + +static void DrawSpeciesIcons(void) +{ + s16 x, y; + u32 i; + u16 species; + + LoadCompressedSpriteSheetUsingHeap(&sNoDataIconSpriteSheet); + for (i = 0; i < LAND_WILD_COUNT; i++) + { + species = sDexNavUiDataPtr->landSpecies[i]; + x = 20 + (24 * (i % 6)); + y = ROW_LAND_TOP_ICON_Y + (i > 5 ? 28 : 0); + TryDrawIconInSlot(species, x, y); + } + + for (i = 0; i < WATER_WILD_COUNT; i++) + { + species = sDexNavUiDataPtr->waterSpecies[i]; + x = 30 + 24 * i; + y = ROW_WATER_ICON_Y; + TryDrawIconInSlot(species, x, y); + } + + for (i = 0; i < HIDDEN_WILD_COUNT; i++) + { + species = sDexNavUiDataPtr->hiddenSpecies[i]; + x = ROW_HIDDEN_ICON_X + 24 * i; + y = ROW_HIDDEN_ICON_Y; + if (FlagGet(FLAG_SYS_DETECTOR_MODE)) + TryDrawIconInSlot(species, x, y); + else if (species == SPECIES_NONE || species > NUM_SPECIES) + CreateNoDataIcon(x, y); + else + CreateMonIcon(SPECIES_NONE, SpriteCB_MonIcon, x, y, 0, 0xFFFFFFFF); //question mark if detector mode inactive + } +} + +static u16 DexNavGetSpecies(void) +{ + u16 species; + + switch (sDexNavUiDataPtr->cursorRow) + { + case ROW_WATER: + species = sDexNavUiDataPtr->waterSpecies[sDexNavUiDataPtr->cursorCol]; + break; + case ROW_LAND_TOP: + species = sDexNavUiDataPtr->landSpecies[sDexNavUiDataPtr->cursorCol]; + break; + case ROW_LAND_BOT: + species = sDexNavUiDataPtr->landSpecies[sDexNavUiDataPtr->cursorCol + COL_LAND_COUNT]; + break; + case ROW_HIDDEN: + if (!FlagGet(FLAG_SYS_DETECTOR_MODE)) + species = SPECIES_NONE; + else + species = sDexNavUiDataPtr->hiddenSpecies[sDexNavUiDataPtr->cursorCol]; + break; + default: + return SPECIES_NONE; + } + + if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN)) + return SPECIES_NONE; + + return species; +} + +static void SetSpriteInvisibility(u8 spriteArrayId, bool8 invisible) +{ + gSprites[sDexNavUiDataPtr->typeIconSpriteIds[spriteArrayId]].invisible = invisible; +} + +// different from pokemon_summary_screen +#define TYPE_ICON_PAL_NUM_0 13 +#define TYPE_ICON_PAL_NUM_1 14 +#define TYPE_ICON_PAL_NUM_2 15 +static const u8 sMoveTypeToOamPaletteNum[NUMBER_OF_MON_TYPES] = +{ + [TYPE_NORMAL] = TYPE_ICON_PAL_NUM_0, + [TYPE_FIGHTING] = TYPE_ICON_PAL_NUM_0, + [TYPE_FLYING] = TYPE_ICON_PAL_NUM_1, + [TYPE_POISON] = TYPE_ICON_PAL_NUM_1, + [TYPE_GROUND] = TYPE_ICON_PAL_NUM_0, + [TYPE_ROCK] = TYPE_ICON_PAL_NUM_0, + [TYPE_BUG] = TYPE_ICON_PAL_NUM_2, + [TYPE_GHOST] = TYPE_ICON_PAL_NUM_1, + [TYPE_STEEL] = TYPE_ICON_PAL_NUM_0, + [TYPE_MYSTERY] = TYPE_ICON_PAL_NUM_2, + [TYPE_FIRE] = TYPE_ICON_PAL_NUM_0, + [TYPE_WATER] = TYPE_ICON_PAL_NUM_1, + [TYPE_GRASS] = TYPE_ICON_PAL_NUM_2, + [TYPE_ELECTRIC] = TYPE_ICON_PAL_NUM_0, + [TYPE_PSYCHIC] = TYPE_ICON_PAL_NUM_1, + [TYPE_ICE] = TYPE_ICON_PAL_NUM_1, + [TYPE_DRAGON] = TYPE_ICON_PAL_NUM_2, + [TYPE_DARK] = TYPE_ICON_PAL_NUM_0, + [TYPE_FAIRY] = TYPE_ICON_PAL_NUM_1, +}; +static void SetTypeIconPosAndPal(u8 typeId, u8 x, u8 y, u8 spriteArrayId) +{ + struct Sprite *sprite; + + sprite = &gSprites[sDexNavUiDataPtr->typeIconSpriteIds[spriteArrayId]]; + StartSpriteAnim(sprite, typeId); + sprite->oam.paletteNum = sMoveTypeToOamPaletteNum[typeId]; + sprite->x = x + 16; + sprite->y = y + 8; + SetSpriteInvisibility(spriteArrayId, FALSE); +} + +static void PrintCurrentSpeciesInfo(void) +{ + u16 species = DexNavGetSpecies(); + u16 dexNum = SpeciesToNationalPokedexNum(species); + u8 type1, type2; + + if (!GetSetPokedexFlag(dexNum, FLAG_GET_SEEN)) + species = SPECIES_NONE; + + // clear windows + FillWindowPixelBuffer(WINDOW_INFO, PIXEL_FILL(TEXT_COLOR_TRANSPARENT)); + + //species name + if (species == SPECIES_NONE) + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, SPECIES_INFO_Y, sFontColor_Black, 0, sText_DexNav_NoInfo); + else + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, SPECIES_INFO_Y, sFontColor_Black, 0, GetSpeciesName(species)); + + //type icon(s) + type1 = gSpeciesInfo[species].types[0]; + type2 = gSpeciesInfo[species].types[1]; + if (species == SPECIES_NONE) + type1 = type2 = TYPE_MYSTERY; + + if (type1 == type2) + { + SetTypeIconPosAndPal(type1, 186, 69, 0); + SetSpriteInvisibility(1, TRUE); + } + else + { + SetTypeIconPosAndPal(type1, 168, 69, 0); + SetTypeIconPosAndPal(type2, 168 + 33, 69, 1); + } + + //search level + if (species == SPECIES_NONE) + { + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, SEARCH_LEVEL_Y, sFontColor_Black, 0, sText_DexNav_NoInfo); + } + else + { + ConvertIntToDecimalStringN(gStringVar4, GetSearchLevel(dexNum), 0, 4); + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, SEARCH_LEVEL_Y, sFontColor_Black, 0, gStringVar4); + } + + //hidden ability + if (species == SPECIES_NONE) + { + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, HA_INFO_Y, sFontColor_Black, 0, sText_DexNav_NoInfo); + } + else if (GetSetPokedexFlag(dexNum, FLAG_GET_CAUGHT)) + { + if (gSpeciesInfo[species].abilities[2] != ABILITY_NONE) + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, HA_INFO_Y, sFontColor_Black, 0, gAbilitiesInfo[gSpeciesInfo[species].abilities[2]].name); + else + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, HA_INFO_Y, sFontColor_Black, 0, gText_None); + } + else + { + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, HA_INFO_Y, sFontColor_Black, 0, sText_DexNav_CaptureToSee); + } + + //current chain + ConvertIntToDecimalStringN(gStringVar1, gSaveBlock3Ptr->dexNavChain, STR_CONV_MODE_LEFT_ALIGN, 3); + AddTextPrinterParameterized3(WINDOW_INFO, 0, 0, CHAIN_BONUS_Y, sFontColor_Black, 0, gStringVar1); + + CopyWindowToVram(WINDOW_INFO, 3); + PutWindowTilemap(WINDOW_INFO); +} + +static void PrintMapName(void) +{ + GetMapName(gStringVar3, GetCurrentRegionMapSectionId(), 0); + AddTextPrinterParameterized3(WINDOW_REGISTERED, 1, 108 + + GetStringRightAlignXOffset(1, gStringVar3, MAP_NAME_LENGTH * GetFontAttribute(1, FONTATTR_MAX_LETTER_WIDTH)), + 0, sFontColor_White, 0, gStringVar3); + CopyWindowToVram(WINDOW_REGISTERED, 3); +} + +static void PrintSearchableSpecies(u16 species) +{ + FillWindowPixelBuffer(WINDOW_REGISTERED, PIXEL_FILL(TEXT_COLOR_TRANSPARENT)); + PutWindowTilemap(WINDOW_REGISTERED); + if (species == SPECIES_NONE) + { + AddTextPrinterParameterized3(WINDOW_REGISTERED, 1, 0, 0, sFontColor_White, TEXT_SKIP_DRAW, sText_DexNav_PressRToRegister); + } + else + { + StringCopy(gStringVar1, GetSpeciesName(species)); + StringExpandPlaceholders(gStringVar4, sText_DexNav_SearchForRegisteredSpecies); + AddTextPrinterParameterized3(WINDOW_REGISTERED, 1, 0, 0, sFontColor_White, TEXT_SKIP_DRAW, gStringVar4); + } + + PrintMapName(); +} + +static void CreateTypeIconSprites(void) +{ + u8 i; + + LoadCompressedSpriteSheet(&gSpriteSheet_MoveTypes); + LoadCompressedPalette(gMoveTypes_Pal, 0x1D0, 0x60); + for (i = 0; i < 2; i++) + { + if (sDexNavUiDataPtr->typeIconSpriteIds[i] == 0xFF) + sDexNavUiDataPtr->typeIconSpriteIds[i] = CreateSprite(&gSpriteTemplate_MoveTypes, 10, 10, 2); + + SetSpriteInvisibility(i, TRUE); + } +} + +static bool8 DexNav_DoGfxSetup(void) +{ + u8 taskId; + + switch (gMain.state) + { + case 0: + SetVBlankHBlankCallbacksToNull(); + ClearScheduledBgCopiesToVram(); + gMain.state++; + break; + case 1: + ScanlineEffect_Stop(); + gMain.state++; + break; + case 2: + FreeAllSpritePalettes(); + gMain.state++; + break; + case 3: + ResetPaletteFade(); + ResetSpriteData(); + ResetTasks(); + gMain.state++; + break; + case 4: + if (DexNav_InitBgs()) + { + sDexNavUiDataPtr->state = 0; + gMain.state++; + } + else + { + DexNavFadeAndExit(); + return TRUE; + } + break; + case 5: + if (DexNav_LoadGraphics() == TRUE) + gMain.state++; + break; + case 6: + DexNav_InitWindows(); + sDexNavUiDataPtr->cursorRow = ROW_LAND_TOP; + sDexNavUiDataPtr->cursorCol = 0; + sDexNavUiDataPtr->environment = ENCOUNTER_TYPE_LAND; + gMain.state++; + break; + case 7: + PrintSearchableSpecies(VarGet(VAR_DEXNAV_SPECIES) & DEXNAV_MASK_SPECIES); + DexNavLoadEncounterData(); + gMain.state++; + break; + case 8: + taskId = CreateTask(Task_DexNavWaitFadeIn, 0); + gTasks[taskId].tSpecies = 0; + gTasks[taskId].tEnvironment = sDexNavUiDataPtr->environment; + gMain.state++; + break; + case 9: + sDexNavUiDataPtr->typeIconSpriteIds[0] = 0xFF; + sDexNavUiDataPtr->typeIconSpriteIds[1] = 0xFF; + CreateTypeIconSprites(); + gMain.state++; + break; + case 10: + LoadMonIconPalettes(); + DrawSpeciesIcons(); + CreateSelectionCursor(); + DexNavLoadCapturedAllSymbols(); + gMain.state++; + break; + case 11: + BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK); + gMain.state++; + break; + case 12: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + gMain.state++; + break; + default: + SetVBlankCallback(DexNav_VBlankCB); + SetMainCallback2(DexNav_MainCB); + return TRUE; + } + + return FALSE; +} + +static void DexNav_RunSetup(void) +{ + while (!DexNav_DoGfxSetup()) {} +} + +// Entry point for the dexnav GUI +static void DexNavGuiInit(MainCallback callback) +{ + if ((sDexNavUiDataPtr = AllocZeroed(sizeof(struct DexNavGUI))) == NULL) + { + SetMainCallback2(callback); + return; + } + + sDexNavUiDataPtr->state = 0; + sDexNavUiDataPtr->savedCallback = callback; + SetMainCallback2(DexNav_RunSetup); +} + +void Task_OpenDexNavFromStartMenu(u8 taskId) +{ + if (DEXNAV_ENABLED == FALSE) + { // must have it enabled to enter + DebugPrintfLevel(MGBA_LOG_ERROR, "DexNav was opened when DEXNAV_ENABLED config was disabled! Check include/config/dexnav.h"); + DestroyTask(taskId); + } + else if (!gPaletteFade.active) + { + CleanupOverworldWindowsAndTilemaps(); + DexNavGuiInit(CB2_ReturnToFieldWithOpenMenu); + DestroyTask(taskId); + } +} + +static void Task_DexNavWaitFadeIn(u8 taskId) +{ + if (!gPaletteFade.active) + gTasks[taskId].func = Task_DexNavMain; +} + +static void Task_DexNavMain(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + u16 species; + + if (IsSEPlaying()) + return; + + if (JOY_NEW(B_BUTTON)) + { + PlaySE(SE_POKENAV_OFF); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + task->func = Task_DexNavFadeAndExit; + } + else if (JOY_NEW(DPAD_UP)) + { + if (sDexNavUiDataPtr->cursorRow == ROW_WATER) + { + sDexNavUiDataPtr->cursorRow = ROW_HIDDEN; + if (sDexNavUiDataPtr->cursorCol >= COL_HIDDEN_COUNT) + sDexNavUiDataPtr->cursorCol = COL_HIDDEN_MAX; + } + else + { + if (sDexNavUiDataPtr->cursorRow == ROW_LAND_TOP && sDexNavUiDataPtr->cursorCol == COL_LAND_MAX) + sDexNavUiDataPtr->cursorCol = COL_WATER_MAX; + + sDexNavUiDataPtr->cursorRow--; + } + + PlaySE(SE_RG_BAG_CURSOR); + UpdateCursorPosition(); + } + else if (JOY_NEW(DPAD_DOWN)) + { + if (sDexNavUiDataPtr->cursorRow == ROW_HIDDEN) + { + sDexNavUiDataPtr->cursorRow = ROW_WATER; + } + else if (sDexNavUiDataPtr->cursorRow == ROW_LAND_BOT) + { + if (sDexNavUiDataPtr->cursorCol >= COL_HIDDEN_COUNT) + sDexNavUiDataPtr->cursorCol = COL_HIDDEN_MAX; + + sDexNavUiDataPtr->cursorRow++; + } + else + { + sDexNavUiDataPtr->cursorRow++; + } + + PlaySE(SE_RG_BAG_CURSOR); + UpdateCursorPosition(); + } + else if (JOY_NEW(DPAD_LEFT)) + { + if (sDexNavUiDataPtr->cursorCol == 0) + { + switch (sDexNavUiDataPtr->cursorRow) + { + case ROW_WATER: + sDexNavUiDataPtr->cursorCol = COL_WATER_MAX; + break; + case ROW_HIDDEN: + sDexNavUiDataPtr->cursorCol = COL_HIDDEN_MAX; + break; + default: + sDexNavUiDataPtr->cursorCol = COL_LAND_MAX; + break; + } + } + else + { + sDexNavUiDataPtr->cursorCol--; + } + + PlaySE(SE_RG_BAG_CURSOR); + UpdateCursorPosition(); + } + else if (JOY_NEW(DPAD_RIGHT)) + { + switch (sDexNavUiDataPtr->cursorRow) + { + case ROW_WATER: + if (sDexNavUiDataPtr->cursorCol == COL_WATER_MAX) + sDexNavUiDataPtr->cursorCol = 0; + else + sDexNavUiDataPtr->cursorCol++; + break; + case ROW_HIDDEN: + if (sDexNavUiDataPtr->cursorCol == COL_HIDDEN_MAX) + sDexNavUiDataPtr->cursorCol = 0; + else + sDexNavUiDataPtr->cursorCol++; + break; + default: + if (sDexNavUiDataPtr->cursorCol == COL_LAND_MAX) + sDexNavUiDataPtr->cursorCol = 0; + else + sDexNavUiDataPtr->cursorCol++; + break; + } + + PlaySE(SE_RG_BAG_CURSOR); + UpdateCursorPosition(); + } + else if (JOY_NEW(R_BUTTON)) + { + // check selection is valid. Play sound if invalid + species = DexNavGetSpecies(); + + if (species != SPECIES_NONE) + { + PrintSearchableSpecies(species); + //PlaySE(SE_DEX_SEARCH); + PlayCry_Script(species, 0); + + // create value to store in a var + VarSet(VAR_DEXNAV_SPECIES, ((sDexNavUiDataPtr->environment << 14) | species)); + } + else + { + PlaySE(SE_FAILURE); + } + } + else if (JOY_NEW(A_BUTTON)) + { + species = DexNavGetSpecies(); + if (species == SPECIES_NONE) + { + PlaySE(SE_FAILURE); + } + else + { + gSpecialVar_0x8000 = species; + gSpecialVar_0x8001 = sDexNavUiDataPtr->environment; + gSpecialVar_0x8002 = (sDexNavUiDataPtr->cursorRow == ROW_HIDDEN) ? TRUE : FALSE; + PlaySE(SE_DEX_SEARCH); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); + task->func = Task_DexNavExitAndSearch; + } + } +} + +///////////////////////// +//// HIDDEN POKEMON ///// +///////////////////////// +bool8 TryFindHiddenPokemon(void) +{ + u16 *stepPtr = GetVarPointer(VAR_DEXNAV_STEP_COUNTER); + + if (DEXNAV_ENABLED == 0 + || !FlagGet(FLAG_SYS_DETECTOR_MODE) + || FlagGet(FLAG_SYS_DEXNAV_SEARCH) + || GetFlashLevel() > 0) + { + (*stepPtr) = 0; + return FALSE; + } + + (*stepPtr)++; + (*stepPtr) %= HIDDEN_MON_STEP_COUNT; + if ((*stepPtr) == 0 && (Random() % 100 < HIDDEN_MON_SEARCH_RATE)) + { + // hidden pokemon + u16 headerId = GetCurrentMapWildMonHeaderId(); + u8 index; + u16 species; + u8 environment; + u8 taskId; + const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo; + bool8 isHiddenMon = FALSE; + + // while you can still technically find hidden pokemon if there are not hidden-only pokemon on a map, + // this prevents any potential lagging on maps you dont want hidden pokemon to appear on + if (hiddenMonsInfo == NULL) + return FALSE; + + // encounter rate signifies surfing (1) or land mons (0)! + // again, for simplicity + switch (hiddenMonsInfo->encounterRate) + { + case 0: // land + // there are surely better ways to do this, but this allows greatest flexibility + if (Random() % 100 < HIDDEN_MON_PROBABILTY) + { + index = ChooseHiddenMonIndex(); + if (index == 0xFF) + return FALSE;//no hidden info + species = hiddenMonsInfo->wildPokemon[index].species; + isHiddenMon = TRUE; + environment = ENCOUNTER_TYPE_HIDDEN; + } + else + { + species = gWildMonHeaders[headerId].landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species; + environment = ENCOUNTER_TYPE_LAND; + } + break; + case 1: // water + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + { + if (Random() % 100 < HIDDEN_MON_PROBABILTY) + { + index = ChooseHiddenMonIndex(); + if (index == 0xFF) + return FALSE;//no hidden info + species = hiddenMonsInfo->wildPokemon[index].species; + isHiddenMon = TRUE; + environment = ENCOUNTER_TYPE_HIDDEN; + } + else + { + species = gWildMonHeaders[headerId].waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species; + environment = ENCOUNTER_TYPE_WATER; + + } + } + else + { + // not surfing -> cant find hidden water mons + return FALSE; + } + break; + default: + return FALSE; + } + + if (species == SPECIES_NONE) + return FALSE; + + sDexNavSearchDataPtr = AllocZeroed(sizeof(struct DexNavSearch)); + + // init search data + sDexNavSearchDataPtr->isHiddenMon = isHiddenMon; + sDexNavSearchDataPtr->species = species; + sDexNavSearchDataPtr->hiddenSearch = TRUE; + sDexNavSearchDataPtr->environment = environment; // updated in DexNavTryGenerateMonLevel if hidden mon + sDexNavSearchDataPtr->monLevel = DexNavTryGenerateMonLevel(species, environment); + if (sDexNavSearchDataPtr->monLevel == MON_LEVEL_NONEXISTENT) + { + Free(sDexNavSearchDataPtr); + return FALSE; + } + + // find tile for hidden mon and start effect if possible + if (!TryStartHiddenMonFieldEffect(sDexNavSearchDataPtr->environment, 8, 8, TRUE)) + return FALSE; + + // exclamation mark over player + gFieldEffectArguments[0] = gSaveBlock1Ptr->pos.x; + gFieldEffectArguments[1] = gSaveBlock1Ptr->pos.y; + gFieldEffectArguments[2] = gSprites[gPlayerAvatar.spriteId].subpriority - 1; + gFieldEffectArguments[3] = 2; + ObjectEventGetLocalIdAndMap(&gObjectEvents[gPlayerAvatar.objectEventId], &gFieldEffectArguments[0], &gFieldEffectArguments[1], &gFieldEffectArguments[2]); + FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON); + + PlayCry_Script(species, 0); + taskId = CreateTask(Task_SetUpDexNavSearch, 0); + gTasks[taskId].tSpecies = sDexNavSearchDataPtr->species; + gTasks[taskId].tEnvironment = sDexNavSearchDataPtr->environment; + gTasks[taskId].tRevealed = FALSE; + HideMapNamePopUpWindow(); + ChangeBgY_ScreenOff(0, 0, 0); + return FALSE; // we dont actually want to enable the script context or the game will freeze + } + + return FALSE; +} + +static void DrawSearchIcon(void) +{ + struct CompressedSpriteSheet spriteSheet; + + spriteSheet.data = sHiddenSearchIconGfx; + spriteSheet.size = 0x200; + spriteSheet.tag = SELECTION_CURSOR_TAG; + LoadCompressedSpriteSheet(&spriteSheet); + sDexNavSearchDataPtr->iconSpriteId = CreateSprite(&sSearchIconSpriteTemplate, 18, GetSearchWindowY() + 12, 0); +} + +// the initial hidden icon window ONLY shows search icon, ??? instead of name, and the search level (and pokeball icon if owned) +// if the player presses R or moves close enough, the full search window will be created +// this way, if the player is not interested in hidden pokemon it will not be too intrusive +static void DrawHiddenSearchWindow(u8 width) +{ + AddSearchWindow(width); + AddTextPrinterParameterized3(sDexNavSearchDataPtr->windowId, 0, SPECIES_ICON_X + 4, 0, sSearchFontColor, TEXT_SKIP_DRAW, sText_ThreeQmarks); + + ConvertIntToDecimalStringN(gStringVar1, sDexNavSearchDataPtr->searchLevel, STR_CONV_MODE_LEFT_ALIGN, 2); + StringExpandPlaceholders(gStringVar4, sText_SearchLevel); + AddTextPrinterParameterized3(sDexNavSearchDataPtr->windowId, 0, SPECIES_ICON_X + 4, 12, sSearchFontColor, TEXT_SKIP_DRAW, gStringVar4); + CopyWindowToVram(sDexNavSearchDataPtr->windowId, 2); +} + +static void DexNavDrawHiddenIcons(void) +{ + u16 species = sDexNavSearchDataPtr->species; + + DrawHiddenSearchWindow(12); + DrawSearchIcon(); + + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + sDexNavSearchDataPtr->ownedIconSpriteId = CreateSprite(&sOwnedIconTemplate, SPECIES_ICON_X + 6, GetSearchWindowY() + 2, 0); + + if (sDexNavSearchDataPtr->isHiddenMon) + sDexNavSearchDataPtr->exclamationSpriteId = CreateSprite(&sHiddenMonIconTemplate, SPECIES_ICON_X + 34, GetSearchWindowY() + 8, 0); +} + +///////////////////////// +//// GENERAL UTILITY //// +///////////////////////// +u32 CalculateDexNavShinyRolls(void) +{ + u32 chainBonus, rndBonus; + u8 chain = gSaveBlock3Ptr->dexNavChain; + + chainBonus = (chain >= 100) ? 10 : (chain >= 50) ? 5 : 0; + rndBonus = (Random() % 100 < 4) ? 4 : 0; + return chainBonus + rndBonus; +} + +void TryIncrementSpeciesSearchLevel(u16 dexNum) +{ +#if USE_DEXNAV_SEARCH_LEVELS == TRUE + if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER && gSaveBlock3Ptr->dexNavSearchLevels[dexNum] < 255) + gSaveBlock3Ptr->dexNavSearchLevels[dexNum]++; +#endif +} + +void ResetDexNavSearch(void) +{ + gSaveBlock3Ptr->dexNavChain = 0; //reset dex nav chaining on new map + VarSet(VAR_DEXNAV_STEP_COUNTER, 0); //reset hidden pokemon step counter + if (FlagGet(FLAG_SYS_DEXNAV_SEARCH)) + EndDexNavSearch(FindTaskIdByFunc(Task_DexNavSearch)); //moving to new map ends dexnav search +} + +void IncrementDexNavChain(void) +{ + if (gSaveBlock3Ptr->dexNavChain < DEXNAV_CHAIN_MAX) + gSaveBlock3Ptr->dexNavChain++; +} diff --git a/src/easy_chat.c b/src/easy_chat.c index ce3b4fe907..aa8405be75 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -17,6 +17,7 @@ #include "main.h" #include "mystery_gift.h" #include "menu.h" +#include "move.h" #include "overworld.h" #include "palette.h" #include "pokedex.h" diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 01b393aa76..c3b8f0facb 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -201,7 +201,6 @@ static bool8 GetFollowerInfo(u16 *species, u8 *form, u8 *shiny); static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny); static const struct ObjectEventGraphicsInfo *SpeciesToGraphicsInfo(u16 species, u8 form); static bool8 NpcTakeStep(struct Sprite *); -static bool8 IsElevationMismatchAt(u8, s16, s16); static bool8 AreElevationsCompatible(u8, u8); static void CopyObjectGraphicsInfoToSpriteTemplate_WithMovementType(u16 graphicsId, u16 movementType, struct SpriteTemplate *spriteTemplate, const struct SubspriteTable **subspriteTables); @@ -2551,7 +2550,7 @@ void GetFollowerAction(struct ScriptContext *ctx) // Essentially a big switch fo } if (multi < NUMBER_OF_MON_TYPES) { - multi = GetTypeEffectiveness(mon, multi); + multi = GetOverworldTypeEffectiveness(mon, multi); if (multi <= UQ_4_12(0.5)) condEmotes[condCount++] = (struct SpecialEmote) {.emotion = FOLLOWER_EMOTION_HAPPY, .index = 32}; else if (multi >= UQ_4_12(2.0)) @@ -9768,7 +9767,7 @@ static void SetObjectEventSpriteOamTableForLongGrass(struct ObjectEvent *objEven sprite->subspriteTableNum = 5; } -static bool8 IsElevationMismatchAt(u8 elevation, s16 x, s16 y) +bool8 IsElevationMismatchAt(u8 elevation, s16 x, s16 y) { u8 mapElevation; diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index 05da7d2041..eabbc202c8 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -4,6 +4,7 @@ #include "coord_event_weather.h" #include "daycare.h" #include "debug.h" +#include "dexnav.h" #include "faraway_island.h" #include "event_data.h" #include "event_object_movement.h" @@ -91,7 +92,7 @@ void FieldClearPlayerInput(struct FieldInput *input) input->heldDirection2 = FALSE; input->tookStep = FALSE; input->pressedBButton = FALSE; - input->input_field_1_0 = FALSE; + input->pressedRButton = FALSE; input->input_field_1_1 = FALSE; input->input_field_1_2 = FALSE; input->input_field_1_3 = FALSE; @@ -116,6 +117,8 @@ void FieldGetPlayerInput(struct FieldInput *input, u16 newKeys, u16 heldKeys) input->pressedAButton = TRUE; if (newKeys & B_BUTTON) input->pressedBButton = TRUE; + if (newKeys & R_BUTTON && !FlagGet(FLAG_SYS_DEXNAV_SEARCH)) + input->pressedRButton = TRUE; } if (heldKeys & (DPAD_UP | DPAD_DOWN | DPAD_LEFT | DPAD_RIGHT)) @@ -222,8 +225,15 @@ int ProcessPlayerFieldInput(struct FieldInput *input) ShowStartMenu(); return TRUE; } + + if (input->tookStep && TryFindHiddenPokemon()) + return TRUE; + if (input->pressedSelectButton && UseRegisteredKeyItemOnField() == TRUE) return TRUE; + + if (input->pressedRButton && TryStartDexNavSearch()) + return TRUE; if(input->input_field_1_2 && DEBUG_OVERWORLD_MENU && !DEBUG_OVERWORLD_IN_MENU) { diff --git a/src/field_effect.c b/src/field_effect.c index cbe311753a..c325d151b9 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -3938,6 +3938,21 @@ static void Task_MoveDeoxysRock(u8 taskId) } } +u8 FldEff_CaveDust(void) +{ + u8 spriteId; + + SetSpritePosToOffsetMapCoords((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8); + spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_CAVE_DUST], gFieldEffectArguments[0], gFieldEffectArguments[1], 0xFF); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].coordOffsetEnabled = TRUE; + gSprites[spriteId].data[0] = 22; + } + + return spriteId; +} + #undef tState #undef tSpriteId #undef tTargetX diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c index 9f8324aee6..a8dfb3d2e7 100644 --- a/src/field_effect_helpers.c +++ b/src/field_effect_helpers.c @@ -1023,7 +1023,7 @@ void UpdateHotSpringsWaterFieldEffect(struct Sprite *sprite) #undef sPrevX #undef sPrevY -u32 FldEff_UnusedGrass(void) +u32 FldEff_ShakingGrass(void) { u8 spriteId; @@ -1034,12 +1034,13 @@ u32 FldEff_UnusedGrass(void) struct Sprite *sprite = &gSprites[spriteId]; sprite->coordOffsetEnabled = TRUE; sprite->oam.priority = gFieldEffectArguments[3]; - sprite->sWaitFldEff = FLDEFF_UNUSED_GRASS; + sprite->sWaitFldEff = FLDEFF_SHAKING_GRASS; } - return 0; + + return spriteId; } -u32 FldEff_UnusedGrass2(void) +u32 FldEff_ShakingGrass2(void) { u8 spriteId; @@ -1050,9 +1051,10 @@ u32 FldEff_UnusedGrass2(void) struct Sprite *sprite = &gSprites[spriteId]; sprite->coordOffsetEnabled = TRUE; sprite->oam.priority = gFieldEffectArguments[3]; - sprite->sWaitFldEff = FLDEFF_UNUSED_GRASS_2; + sprite->sWaitFldEff = FLDEFF_SHAKING_LONG_GRASS; } - return 0; + + return spriteId; } u32 FldEff_UnusedSand(void) @@ -1066,9 +1068,9 @@ u32 FldEff_UnusedSand(void) struct Sprite *sprite = &gSprites[spriteId]; sprite->coordOffsetEnabled = TRUE; sprite->oam.priority = gFieldEffectArguments[3]; - sprite->sWaitFldEff = FLDEFF_UNUSED_SAND; + sprite->sWaitFldEff = FLDEFF_SAND_HOLE; } - return 0; + return spriteId; } u32 FldEff_WaterSurfacing(void) @@ -1084,7 +1086,8 @@ u32 FldEff_WaterSurfacing(void) sprite->oam.priority = gFieldEffectArguments[3]; sprite->sWaitFldEff = FLDEFF_WATER_SURFACING; } - return 0; + + return spriteId; } // Sprite data for FLDEFF_ASH @@ -1482,7 +1485,7 @@ u32 FldEff_BerryTreeGrowthSparkle(void) UpdateSpritePaletteByTemplate(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_SPARKLE], sprite); sprite->sWaitFldEff = FLDEFF_BERRY_TREE_GROWTH_SPARKLE; } - return 0; + return spriteId; } // Sprite data for FLDEFF_TREE_DISGUISE / FLDEFF_MOUNTAIN_DISGUISE / FLDEFF_SAND_DISGUISE @@ -1610,7 +1613,7 @@ u32 FldEff_Sparkle(void) gSprites[spriteId].oam.priority = gFieldEffectArguments[2]; gSprites[spriteId].coordOffsetEnabled = TRUE; } - return 0; + return spriteId; } void UpdateSparkleFieldEffect(struct Sprite *sprite) @@ -1874,27 +1877,3 @@ static void UpdateGrassFieldEffectSubpriority(struct Sprite *sprite, u8 elevatio } } -// Unused, duplicates of data in event_object_movement.c -static const s8 sFigure8XOffsets[FIGURE_8_LENGTH] = { - 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 2, 2, 1, 2, - 2, 1, 2, 2, 1, 2, 1, 1, - 2, 1, 1, 2, 1, 1, 2, 1, - 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 0, - 1, 0, 1, 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, -}; - -static const s8 sFigure8YOffsets[FIGURE_8_LENGTH] = { - 0, 0, 1, 0, 0, 1, 0, 0, - 1, 0, 1, 1, 0, 1, 1, 0, - 1, 1, 0, 1, 1, 0, 1, 1, - 0, 0, 1, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -1, 0, 0, -1, 0, 0, - -1, 0, -1, -1, 0, -1, -1, 0, - -1, -1, -1, -1, -1, -1, -1, -2, -}; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index ebf61bdaa3..9abb81a18e 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -665,11 +665,20 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) return; } } - + + gPlayerAvatar.creeping = FALSE; if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) { - // same speed as running - PlayerWalkFast(direction); + if (FlagGet(FLAG_SYS_DEXNAV_SEARCH) && (heldKeys & A_BUTTON)) + { + gPlayerAvatar.creeping = TRUE; + PlayerWalkSlow(direction); + } + else + { + // speed 2 is fast, same speed as running + PlayerWalkFast(direction); + } return; } @@ -684,6 +693,11 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH; return; } + else if (FlagGet(FLAG_SYS_DEXNAV_SEARCH) && (heldKeys & A_BUTTON)) + { + gPlayerAvatar.creeping = TRUE; + PlayerWalkSlow(direction); + } else { if (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index 553f68c874..be0e9bd792 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -1376,7 +1376,6 @@ static void Task_RushInjuredPokemonToCenter(u8 taskId) ClearWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_MAP); RemoveWindow(windowId); - FillPalBufferBlack(); FadeInFromBlack(); gTasks[taskId].tState = FRLG_WHITEOUT_HEAL_SCRIPT; break; diff --git a/src/field_specials.c b/src/field_specials.c index 5ca6134bc5..1353d197f4 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -2776,10 +2776,12 @@ static void ScrollableMultichoice_UpdateScrollArrows(u8 taskId) struct ScrollArrowsTemplate template = sScrollableMultichoice_ScrollArrowsTemplate; if (task->tMaxItemsOnScreen != task->tNumItems) { + u32 y0 = (8 * (task->tTop - 1)); + template.firstX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8; - template.firstY = 8; + template.firstY = 8 + y0; template.secondX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8; - template.secondY = task->tHeight * 8 + 10; + template.secondY = task->tHeight * 8 + 10 + y0; template.fullyUpThreshold = 0; template.fullyDownThreshold = task->tNumItems - task->tMaxItemsOnScreen; task->tScrollArrowId = AddScrollIndicatorArrowPair(&template, &gScrollableMultichoice_ScrollOffset); diff --git a/src/frontier_util.c b/src/frontier_util.c index 4424676644..30c22d4442 100644 --- a/src/frontier_util.c +++ b/src/frontier_util.c @@ -2543,7 +2543,7 @@ void CreateFrontierBrainPokemon(void) for (j = 0; j < MAX_MON_MOVES; j++) { SetMonMoveSlot(&gEnemyParty[monPartyId], sFrontierBrainsMons[facility][symbol][i].moves[j], j); - if (gMovesInfo[sFrontierBrainsMons[facility][symbol][i].moves[j]].effect == EFFECT_FRUSTRATION) + if (GetMoveEffect(sFrontierBrainsMons[facility][symbol][i].moves[j]) == EFFECT_FRUSTRATION) friendship = 0; } SetMonData(&gEnemyParty[monPartyId], MON_DATA_FRIENDSHIP, &friendship); diff --git a/src/generational_changes.c b/src/generational_changes.c new file mode 100644 index 0000000000..1ad29aa675 --- /dev/null +++ b/src/generational_changes.c @@ -0,0 +1,19 @@ +#include "global.h" +#include "generational_changes.h" +#include "malloc.h" +#include "constants/generational_changes.h" + +#if TESTING +EWRAM_DATA u8 *gGenerationalChangesTestOverride = NULL; + +void TestInitConfigData(void) +{ + gGenerationalChangesTestOverride = Alloc(sizeof(sGenerationalChanges)); + memcpy(gGenerationalChangesTestOverride, sGenerationalChanges, sizeof(sGenerationalChanges)); +} + +void TestFreeConfigData(void) +{ + TRY_FREE_AND_SET_NULL(gGenerationalChangesTestOverride) +} +#endif diff --git a/src/item_icon.c b/src/item_icon.c index 14a812b7fa..03b56918be 100644 --- a/src/item_icon.c +++ b/src/item_icon.c @@ -1,12 +1,13 @@ #include "global.h" +#include "battle_main.h" #include "decompress.h" #include "graphics.h" +#include "item.h" #include "item_icon.h" #include "malloc.h" +#include "move.h" #include "sprite.h" #include "constants/items.h" -#include "item.h" -#include "battle_main.h" // EWRAM vars EWRAM_DATA u8 *gItemIconDecompressionBuffer = NULL; @@ -182,7 +183,7 @@ const void *GetItemIconPalette(u16 itemId) if (itemId >= ITEMS_COUNT) return gItemsInfo[0].iconPalette; if (itemId >= ITEM_TM01 && itemId < ITEM_HM01 + NUM_HIDDEN_MACHINES) - return gTypesInfo[gMovesInfo[gItemsInfo[itemId].secondaryId].type].paletteTMHM; + return gTypesInfo[GetMoveType(gItemsInfo[itemId].secondaryId)].paletteTMHM; return gItemsInfo[itemId].iconPalette; } diff --git a/src/item_menu.c b/src/item_menu.c index 75751cae6f..ff5d569f96 100755 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -2604,34 +2604,36 @@ static void PrintTMHMMoveData(u16 itemId) else { moveId = ItemIdToBattleMoveId(itemId); - BlitMenuInfoIcon(WIN_TMHM_INFO, gMovesInfo[moveId].type + 1, 0, 0); + BlitMenuInfoIcon(WIN_TMHM_INFO, GetMoveType(moveId) + 1, 0, 0); // Print TMHM power - if (gMovesInfo[moveId].power <= 1) + u32 power = GetMovePower(moveId); + if (power <= 1) { text = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].power, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3); text = gStringVar1; } BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 12, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO); + u32 accuracy = GetMoveAccuracy(moveId); // Print TMHM accuracy - if (gMovesInfo[moveId].accuracy == 0) + if (accuracy == 0) { text = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); text = gStringVar1; } BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 24, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO); // Print TMHM pp - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].pp, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, GetMovePP(moveId), STR_CONV_MODE_RIGHT_ALIGN, 3); BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, gStringVar1, 7, 36, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO); CopyWindowToVram(WIN_TMHM_INFO, COPYWIN_GFX); diff --git a/src/m4a.c b/src/m4a.c index e90e9b06f0..493577cc23 100644 --- a/src/m4a.c +++ b/src/m4a.c @@ -6,8 +6,6 @@ extern const u8 gCgb3Vol[]; #define BSS_CODE __attribute__((section(".bss.code"))) -BSS_CODE ALIGNED(4) char SoundMainRAM_Buffer[0x800] = {0}; - COMMON_DATA struct SoundInfo gSoundInfo = {0}; COMMON_DATA struct PokemonCrySong gPokemonCrySongs[MAX_POKEMON_CRIES] = {0}; COMMON_DATA struct MusicPlayerInfo gPokemonCryMusicPlayers[MAX_POKEMON_CRIES] = {0}; @@ -72,8 +70,6 @@ void m4aSoundInit(void) { s32 i; - CpuCopy32((void *)((s32)SoundMainRAM & ~1), SoundMainRAM_Buffer, sizeof(SoundMainRAM_Buffer)); - SoundInit(&gSoundInfo); MPlayExtender(gCgbChans); m4aSoundMode(SOUND_MODE_DA_BIT_8 diff --git a/src/m4a_1.s b/src/m4a_1.s index 20f9197a8d..4c0c8f7f89 100644 --- a/src/m4a_1.s +++ b/src/m4a_1.s @@ -52,11 +52,11 @@ SoundMain_3: cmp r3, 0 beq SoundMain_4 ldr r0, [r0, o_SoundInfo_musicPlayerHead] - bl _081DD25E + bl call_r3 ldr r0, [sp, 0x18] SoundMain_4: ldr r3, [r0, o_SoundInfo_CgbSound] - bl _081DD25E + bl call_r3 ldr r0, [sp, 0x18] ldr r3, [r0, o_SoundInfo_pcmSamplesPerVBlank] mov r8, r3 @@ -73,18 +73,19 @@ SoundMain_4: SoundMain_5: str r5, [sp, 0x8] ldr r6, lt_PCM_DMA_BUF_SIZE - ldr r3, lt_SoundMainRAM_Buffer + ldr r3, lt_SoundMainRAM bx r3 .align 2, 0 lt_SOUND_INFO_PTR: .word SOUND_INFO_PTR lt_ID_NUMBER: .word ID_NUMBER -lt_SoundMainRAM_Buffer: .word SoundMainRAM_Buffer + 1 +lt_SoundMainRAM: .word SoundMainRAM + 1 lt_REG_VCOUNT: .word REG_VCOUNT lt_o_SoundInfo_pcmBuffer: .word o_SoundInfo_pcmBuffer lt_PCM_DMA_BUF_SIZE: .word PCM_DMA_BUF_SIZE thumb_func_end SoundMain + .section .iwram.code thumb_func_start SoundMainRAM SoundMainRAM: ldrb r3, [r0, o_SoundInfo_reverb] @@ -708,6 +709,7 @@ _081DD594: .pool arm_func_end SoundMainRAM_Unk2 + .text thumb_func_start SoundMainBTM SoundMainBTM: mov r12, r4 diff --git a/src/main.c b/src/main.c index 29f02c20e4..39b4f7e7a7 100644 --- a/src/main.c +++ b/src/main.c @@ -69,7 +69,6 @@ COMMON_DATA u16 gKeyRepeatContinueDelay = 0; COMMON_DATA bool8 gSoftResetDisabled = 0; COMMON_DATA IntrFunc gIntrTable[INTR_COUNT] = {0}; COMMON_DATA u8 gLinkVSyncDisabled = 0; -COMMON_DATA u32 IntrMain_Buffer[0x200] = {0}; COMMON_DATA s8 gPcmDmaCounter = 0; COMMON_DATA void *gAgbMainLoop_sp = NULL; @@ -316,9 +315,7 @@ void InitIntrHandlers(void) for (i = 0; i < INTR_COUNT; i++) gIntrTable[i] = gIntrTableTemplate[i]; - DmaCopy32(3, IntrMain, IntrMain_Buffer, sizeof(IntrMain_Buffer)); - - INTR_VECTOR = IntrMain_Buffer; + INTR_VECTOR = IntrMain; SetVBlankCallback(NULL); SetHBlankCallback(NULL); diff --git a/src/menu_specialized.c b/src/menu_specialized.c index 693e9f12bc..7b6d94b5f2 100644 --- a/src/menu_specialized.c +++ b/src/menu_specialized.c @@ -10,6 +10,7 @@ #include "international_string_util.h" #include "menu.h" #include "menu_specialized.h" +#include "move.h" #include "move_relearner.h" #include "palette.h" #include "player_pc.h" @@ -752,7 +753,6 @@ u8 LoadMoveRelearnerMovesList(const struct ListMenuItem *items, u16 numChoices) static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove) { s32 x; - const struct MoveInfo *move; u8 buffer[32]; const u8 *str; @@ -780,49 +780,41 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove) CopyWindowToVram(RELEARNERWIN_DESC_BATTLE, COPYWIN_GFX); return; } - move = &gMovesInfo[chosenMove]; - str = gTypesInfo[move->type].name; + str = gTypesInfo[GetMoveType(chosenMove)].name; AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL); x = 4 + GetStringWidth(FONT_NORMAL, gText_MoveRelearnerPP, 0); - ConvertIntToDecimalStringN(buffer, move->pp, STR_CONV_MODE_LEFT_ALIGN, 2); + ConvertIntToDecimalStringN(buffer, GetMovePP(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 2); AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, buffer, x, 41, TEXT_SKIP_DRAW, NULL); - if (move->power < 2) + if (GetMovePower(chosenMove) < 2) { str = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(buffer, move->power, STR_CONV_MODE_LEFT_ALIGN, 3); + ConvertIntToDecimalStringN(buffer, GetMovePower(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 3); str = buffer; } AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 25, TEXT_SKIP_DRAW, NULL); - if (move->accuracy == 0) + if (GetMoveAccuracy(chosenMove) == 0) { str = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(buffer, move->accuracy, STR_CONV_MODE_LEFT_ALIGN, 3); + ConvertIntToDecimalStringN(buffer, GetMoveAccuracy(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 3); str = buffer; } AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 41, TEXT_SKIP_DRAW, NULL); - - if (move->effect != EFFECT_PLACEHOLDER) - str = gMovesInfo[chosenMove].description; - else - str = gNotDoneYetDescription; - - AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NARROW, str, 0, 65, 0, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NARROW, GetMoveDescription(chosenMove), 0, 65, 0, NULL); } static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove) { s32 x; const u8 *str; - const struct MoveInfo *move; MoveRelearnerShowHideHearts(chosenMove); FillWindowPixelBuffer(RELEARNERWIN_DESC_CONTEST, PIXEL_FILL(1)); @@ -844,11 +836,10 @@ static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove) return; } - move = &gMovesInfo[chosenMove]; - str = gContestMoveTypeTextPointers[move->contestCategory]; + str = gContestMoveTypeTextPointers[GetMoveContestCategory(chosenMove)]; AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL); - str = gContestEffectDescriptionPointers[move->contestEffect]; + str = gContestEffectDescriptionPointers[GetMoveContestEffect(chosenMove)]; AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NARROW, str, 0, 65, TEXT_SKIP_DRAW, NULL); CopyWindowToVram(RELEARNERWIN_DESC_CONTEST, COPYWIN_GFX); diff --git a/src/move.c b/src/move.c new file mode 100644 index 0000000000..c77742c30e --- /dev/null +++ b/src/move.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "battle.h" +#include "main.h" +#include "move.h" + +#include "data/moves_info.h" diff --git a/src/move_relearner.c b/src/move_relearner.c index 1e66702695..f81e9ddc37 100644 --- a/src/move_relearner.c +++ b/src/move_relearner.c @@ -969,7 +969,7 @@ void MoveRelearnerShowHideHearts(s32 moveId) } else { - numHearts = (u8)(gContestEffects[gMovesInfo[moveId].contestEffect].appeal / 10); + numHearts = (u8)(gContestEffects[GetMoveContestEffect(moveId)].appeal / 10); if (numHearts == 0xFF) numHearts = 0; @@ -983,7 +983,7 @@ void MoveRelearnerShowHideHearts(s32 moveId) gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = FALSE; } - numHearts = (u8)(gContestEffects[gMovesInfo[moveId].contestEffect].jam / 10); + numHearts = (u8)(gContestEffects[GetMoveContestEffect(moveId)].jam / 10); if (numHearts == 0xFF) numHearts = 0; diff --git a/src/new_game.c b/src/new_game.c index 4bce5a5b96..0837475971 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -44,6 +44,7 @@ #include "berry_powder.h" #include "mystery_gift.h" #include "union_room_chat.h" +#include "constants/map_groups.h" #include "constants/items.h" extern const u8 EventScript_ResetAllMapFlags[]; @@ -52,6 +53,7 @@ static void ClearFrontierRecord(void); static void WarpToTruck(void); static void ResetMiniGamesRecords(void); static void ResetItemFlags(void); +static void ResetDexNav(void); EWRAM_DATA bool8 gDifferentSaveFile = FALSE; EWRAM_DATA bool8 gEnableContestDebugging = FALSE; @@ -206,6 +208,7 @@ void NewGameInitData(void) ResetTrainerHillResults(); ResetContestLinkResults(); ResetItemFlags(); + ResetDexNav(); } static void ResetMiniGamesRecords(void) @@ -222,3 +225,11 @@ static void ResetItemFlags(void) memset(&gSaveBlock3Ptr->itemFlags, 0, sizeof(gSaveBlock3Ptr->itemFlags)); #endif } + +static void ResetDexNav(void) +{ +#if USE_DEXNAV_SEARCH_LEVELS == TRUE + memset(gSaveBlock3Ptr->dexNavSearchLevels, 0, sizeof(gSaveBlock3Ptr->dexNavSearchLevels)); +#endif + gSaveBlock3Ptr->dexNavChain = 0; +} diff --git a/src/overworld.c b/src/overworld.c index 30b65a1f1d..58d60e8d2b 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -6,6 +6,7 @@ #include "bg.h" #include "cable_club.h" #include "clock.h" +#include "dexnav.h" #include "event_data.h" #include "event_object_movement.h" #include "event_scripts.h" @@ -844,6 +845,7 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum) LoadObjEventTemplatesFromHeader(); TrySetMapSaveWarpStatus(); ClearTempFieldEventData(); + ResetDexNavSearch(); ResetCyclingRoadChallengeData(); RestartWildEncounterImmunitySteps(); #if FREE_MATCH_CALL == FALSE @@ -907,6 +909,7 @@ static void LoadMapFromWarp(bool32 a1) CheckLeftFriendsSecretBase(); TrySetMapSaveWarpStatus(); ClearTempFieldEventData(); + ResetDexNavSearch(); ResetCyclingRoadChallengeData(); RestartWildEncounterImmunitySteps(); #if FREE_MATCH_CALL == FALSE diff --git a/src/party_menu.c b/src/party_menu.c index 064a0eec16..416bbd7898 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -2735,7 +2735,7 @@ static u8 DisplaySelectionWindow(u8 windowType) const u8 *text; u8 fontColorsId = (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) ? 4 : 3; if (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) - text = gMovesInfo[sFieldMoves[sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES]].name; + text = GetMoveName(sFieldMoves[sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES]); else text = sCursorOptions[sPartyMenuInternal->actions[i]].text; @@ -4259,7 +4259,7 @@ static void ShowOrHideHeldItemSprite(u16 item, struct PartyMenuBox *menuBox) void LoadHeldItemIcons(void) { - LoadSpriteSheet(&sSpriteSheet_HeldItem); + LoadSpriteSheet(&gSpriteSheet_HeldItem); LoadSpritePalette(&sSpritePalette_HeldItem); } diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c index 8782044769..50a00c22b8 100644 --- a/src/pokedex_plus_hgss.c +++ b/src/pokedex_plus_hgss.c @@ -5182,12 +5182,12 @@ static void PrintStatsScreen_Moves_Top(u8 taskId) //Draw move type icon if (gTasks[taskId].data[5] == 0) { - SetTypeIconPosAndPal(gMovesInfo[move].type, moves_x + 146, moves_y + 17, 0); + SetTypeIconPosAndPal(GetMoveType(move), moves_x + 146, moves_y + 17, 0); SetSpriteInvisibility(1, TRUE); } else { - SetTypeIconPosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[move].contestCategory, moves_x + 146, moves_y + 17, 1); + SetTypeIconPosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(move), moves_x + 146, moves_y + 17, 1); SetSpriteInvisibility(0, TRUE); } @@ -5243,12 +5243,12 @@ static void PrintStatsScreen_Moves_Description(u8 taskId) //Move description if (gTasks[taskId].data[5] == 0) { - StringCopy(gStringVar4, gMovesInfo[move].description); + StringCopy(gStringVar4, GetMoveDescription(move)); PrintStatsScreenTextSmall(WIN_STATS_MOVES_DESCRIPTION, gStringVar4, moves_x, moves_y); } else { - StringCopy(gStringVar4, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect]); + StringCopy(gStringVar4, gContestEffectDescriptionPointers[GetMoveContestEffect(move)]); PrintStatsScreenTextSmall(WIN_STATS_MOVES_DESCRIPTION, gStringVar4, moves_x, moves_y); } } @@ -5287,19 +5287,21 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId) if (gTasks[taskId].data[5] == 0) { //Power - if (gMovesInfo[move].power < 2) + u32 power = GetMovePower(move); + if (power < 2) StringCopy(gStringVar1, gText_ThreeDashes); else - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].power, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3); PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar1, moves_x + 45, moves_y); //Physical/Special/Status Category DestroyCategoryIcon(); ShowCategoryIcon(GetBattleMoveCategory(move)); //Accuracy - if (gMovesInfo[move].accuracy == 0) + u32 accuracy = GetMoveAccuracy(move); + if (accuracy == 0) StringCopy(gStringVar1, gText_ThreeDashes); else - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar1, moves_x + 114, moves_y); } else //Appeal + Jam @@ -5307,7 +5309,7 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId) DestroyCategoryIcon(); gSprites[sPokedexView->categoryIconSpriteId].invisible = TRUE; //Appeal - contest_effectValue = gContestEffects[gMovesInfo[move].contestEffect].appeal; + contest_effectValue = gContestEffects[GetMoveContestEffect(move)].appeal; if (contest_effectValue != 0xFF) contest_appeal = contest_effectValue / 10; ConvertIntToDecimalStringN(gStringVar1, contest_appeal, STR_CONV_MODE_RIGHT_ALIGN, 1); @@ -5316,7 +5318,7 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId) PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar2, moves_x + 45, moves_y); //Jam - contest_effectValue = gContestEffects[gMovesInfo[move].contestEffect].jam; + contest_effectValue = gContestEffects[GetMoveContestEffect(move)].jam; if (contest_effectValue != 0xFF) contest_jam = contest_effectValue / 10; ConvertIntToDecimalStringN(gStringVar1, contest_jam, STR_CONV_MODE_RIGHT_ALIGN, 1); diff --git a/src/pokemon.c b/src/pokemon.c index 835c635f96..241372f64a 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -12,6 +12,7 @@ #include "battle_tower.h" #include "battle_z_move.h" #include "data.h" +#include "dexnav.h" #include "event_data.h" #include "event_object_movement.h" #include "evolution_scene.h" @@ -39,6 +40,7 @@ #include "string_util.h" #include "strings.h" #include "task.h" +#include "test_runner.h" #include "text.h" #include "trainer_hill.h" #include "util.h" @@ -47,6 +49,7 @@ #include "constants/battle_move_effects.h" #include "constants/battle_script_commands.h" #include "constants/battle_partner.h" +#include "constants/battle_string_ids.h" #include "constants/cries.h" #include "constants/event_objects.h" #include "constants/form_change_types.h" @@ -75,7 +78,6 @@ static void EncryptBoxMon(struct BoxPokemon *boxMon); static void DecryptBoxMon(struct BoxPokemon *boxMon); static void Task_PlayMapChosenOrBattleBGM(u8 taskId); static bool8 ShouldSkipFriendshipChange(void); -static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv); void TrySpecialOverworldEvo(); EWRAM_DATA static u8 sLearningMoveTableID = 0; @@ -88,7 +90,6 @@ EWRAM_DATA static struct MonSpritesGfxManager *sMonSpritesGfxManagers[MON_SPR_GF EWRAM_DATA static u8 sTriedEvolving = 0; EWRAM_DATA u16 gFollowerSteps = 0; -#include "data/moves_info.h" #include "data/abilities.h" // Used in an unreferenced function in RS. @@ -1162,6 +1163,8 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, totalRerolls += 1; if (I_FISHING_CHAIN && gIsFishingEncounter) totalRerolls += CalculateChainFishingShinyRolls(); + if (gDexNavBattle) + totalRerolls += CalculateDexNavShinyRolls(); while (GET_SHINY_VALUE(value, personality) >= SHINY_ODDS && totalRerolls > 0) { @@ -1868,8 +1871,9 @@ u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move) u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL); if (existingMove == MOVE_NONE) { + u32 pp = GetMovePP(move); SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move); - SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[move].pp); + SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp); return move; } if (existingMove == move) @@ -1887,7 +1891,7 @@ u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move) if (mon->moves[i] == MOVE_NONE) { mon->moves[i] = move; - mon->pp[i] = gMovesInfo[move].pp; + mon->pp[i] = GetMovePP(move); return move; } } @@ -1898,7 +1902,8 @@ u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move) void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot) { SetMonData(mon, MON_DATA_MOVE1 + slot, &move); - SetMonData(mon, MON_DATA_PP1 + slot, &gMovesInfo[move].pp); + u32 pp = GetMovePP(move); + SetMonData(mon, MON_DATA_PP1 + slot, &pp); } static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot) @@ -1915,7 +1920,7 @@ static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot) void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot) { mon->moves[slot] = move; - mon->pp[slot] = gMovesInfo[move].pp; + mon->pp[slot] = GetMovePP(move); } void GiveMonInitialMoveset(struct Pokemon *mon) @@ -1969,7 +1974,8 @@ void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) //Credit: AsparagusEdua for (i = 0; i < MAX_MON_MOVES; i++) { SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]); - SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[moves[i]].pp); + u32 pp = GetMovePP(moves[i]); + SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp); } } @@ -2022,7 +2028,7 @@ void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move) ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); ppBonuses >>= 2; moves[MAX_MON_MOVES - 1] = move; - pp[MAX_MON_MOVES - 1] = gMovesInfo[move].pp; + pp[MAX_MON_MOVES - 1] = GetMovePP(move); for (i = 0; i < MAX_MON_MOVES; i++) { @@ -2049,7 +2055,7 @@ void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move) ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL); ppBonuses >>= 2; moves[MAX_MON_MOVES - 1] = move; - pp[MAX_MON_MOVES - 1] = gMovesInfo[move].pp; + pp[MAX_MON_MOVES - 1] = GetMovePP(move); for (i = 0; i < MAX_MON_MOVES; i++) { @@ -3510,7 +3516,8 @@ void CreateSecretBaseEnemyParty(struct SecretBase *secretBaseRecord) for (j = 0; j < MAX_MON_MOVES; j++) { SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]); - SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gMovesInfo[gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]].pp); + u32 pp = GetMovePP(gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]); + SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &pp); } } } @@ -3635,7 +3642,7 @@ const struct FormChange *GetSpeciesFormChanges(u16 species) u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex) { - u8 basePP = gMovesInfo[move].pp; + u8 basePP = GetMovePP(move); return basePP + ((basePP * 20 * ((gPPUpGetMask[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100); } @@ -4618,7 +4625,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 { for (j = 0; j < MAX_MON_MOVES; j++) { - if (gMovesInfo[GetMonData(mon, MON_DATA_MOVE1 + j, NULL)].type == evolutions[i].param) + if (GetMoveType(GetMonData(mon, MON_DATA_MOVE1 + j, NULL)) == evolutions[i].param) { targetSpecies = evolutions[i].targetSpecies; break; @@ -6302,7 +6309,7 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality) bool8 HasTwoFramesAnimation(u16 species) { - return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN; + return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN && !gTestRunnerHeadless; } static bool8 ShouldSkipFriendshipChange(void) @@ -6684,7 +6691,9 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove) return 0; } -static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) +// Removes the selected index from the given IV list and shifts the remaining +// elements to the left. +void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) { s32 i, j; u8 temp[NUM_STATS]; @@ -6920,7 +6929,7 @@ void HealBoxPokemon(struct BoxPokemon *boxMon) u16 GetCryIdBySpecies(u16 species) { species = SanitizeSpeciesId(species); - if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT) + if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT || gTestRunnerHeadless) return CRY_NONE; return gSpeciesInfo[species].cryId; } @@ -6944,21 +6953,6 @@ u16 GetSpeciesPreEvolution(u16 species) return SPECIES_NONE; } -const u8 *GetMoveName(u16 moveId) -{ - return gMovesInfo[moveId].name; -} - -const u8 *GetMoveAnimationScript(u16 moveId) -{ - if (gMovesInfo[moveId].battleAnimScript == NULL) - { - DebugPrintfLevel(MGBA_LOG_WARN, "No animation for moveId=%u", moveId); - return gMovesInfo[MOVE_NONE].battleAnimScript; - } - return gMovesInfo[moveId].battleAnimScript; -} - void UpdateDaysPassedSinceFormChange(u16 days) { u32 i; @@ -6999,5 +6993,5 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) u32 moveType = GetDynamicMoveType(mon, move, battler, NULL); if (moveType != TYPE_NONE) return moveType; - return gMovesInfo[move].type; + return GetMoveType(move); } diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c index d7c0bb343c..6bd32ee514 100644 --- a/src/pokemon_animation.c +++ b/src/pokemon_animation.c @@ -5,6 +5,7 @@ #include "pokemon_animation.h" #include "sprite.h" #include "task.h" +#include "test_runner.h" #include "trig.h" #include "util.h" #include "data.h" @@ -508,7 +509,10 @@ static void Task_HandleMonAnimation(u8 taskId) for (i = 2; i < ARRAY_COUNT(sprite->data); i++) sprite->data[i] = 0; - sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId]; + if (gTestRunnerHeadless) + sprite->callback = WaitAnimEnd; + else + sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId]; sIsSummaryAnim = FALSE; gTasks[taskId].tState++; diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 735bc84850..913d55fc0d 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -2836,7 +2836,7 @@ static void DrawContestMoveHearts(u16 move) if (move != MOVE_NONE) { // Draw appeal hearts - u8 effectValue = gContestEffects[gMovesInfo[move].contestEffect].appeal; + u8 effectValue = gContestEffects[GetMoveContestEffect(move)].appeal; if (effectValue != 0xFF) effectValue /= 10; @@ -2849,7 +2849,7 @@ static void DrawContestMoveHearts(u16 move) } // Draw jam hearts - effectValue = gContestEffects[gMovesInfo[move].contestEffect].jam; + effectValue = gContestEffects[GetMoveContestEffect(move)].jam; if (effectValue != 0xFF) effectValue /= 10; @@ -3750,29 +3750,31 @@ static void PrintMoveNameAndPP(u8 moveIndex) static void PrintMovePowerAndAccuracy(u16 moveIndex) { const u8 *text; - if (moveIndex != 0) + if (moveIndex != MOVE_NONE) { FillWindowPixelRect(PSS_LABEL_WINDOW_MOVES_POWER_ACC, PIXEL_FILL(0), 53, 0, 19, 32); - if (gMovesInfo[moveIndex].power < 2) + u32 power = GetMovePower(moveIndex); + if (power < 2) { text = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveIndex].power, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3); text = gStringVar1; } PrintTextOnWindow(PSS_LABEL_WINDOW_MOVES_POWER_ACC, text, 53, 1, 0, 0); - if (gMovesInfo[moveIndex].accuracy == 0) + u32 accuracy = GetMoveAccuracy(moveIndex); + if (accuracy == 0) { text = gText_ThreeDashes; } else { - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveIndex].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); text = gStringVar1; } @@ -3842,32 +3844,26 @@ static void PrintContestMoveDescription(u8 moveSlot) if (move != MOVE_NONE) { u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION); - PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect], 6, 1, 0, 0); + PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[GetMoveContestEffect(move)], 6, 1, 0, 0); } } static void PrintMoveDetails(u16 move) { u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION); - u8 moveEffect; FillWindowPixelBuffer(windowId, PIXEL_FILL(0)); if (move != MOVE_NONE) { if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES) { - moveEffect = gMovesInfo[move].effect; if (B_SHOW_CATEGORY_ICON == TRUE) ShowCategoryIcon(GetBattleMoveCategory(move)); PrintMovePowerAndAccuracy(move); - - if (moveEffect != EFFECT_PLACEHOLDER) - PrintTextOnWindow(windowId, gMovesInfo[move].description, 6, 1, 0, 0); - else - PrintTextOnWindow(windowId, gNotDoneYetDescription, 6, 1, 0, 0); + PrintTextOnWindow(windowId, GetMoveDescription(move), 6, 1, 0, 0); } else { - PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect], 6, 1, 0, 0); + PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[GetMoveContestEffect(move)], 6, 1, 0, 0); } PutWindowTilemap(windowId); } @@ -3897,7 +3893,7 @@ static void PrintNewMoveDetailsOrCancelText(void) else PrintTextOnWindowToFit(windowId1, GetMoveName(move), 0, 65, 0, 5); - ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].pp, STR_CONV_MODE_RIGHT_ALIGN, 2); + ConvertIntToDecimalStringN(gStringVar1, GetMovePP(move), STR_CONV_MODE_RIGHT_ALIGN, 2); DynamicPlaceholderTextUtil_Reset(); DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1); DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gStringVar1); @@ -4051,7 +4047,7 @@ static void SetMoveTypeIcons(void) { if (summary->moves[i] != MOVE_NONE) { - type = gMovesInfo[summary->moves[i]].type; + type = GetMoveType(summary->moves[i]); if (P_SHOW_DYNAMIC_TYPES) type = CheckDynamicMoveType(mon, summary->moves[i], 0); SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); @@ -4070,7 +4066,7 @@ static void SetContestMoveTypeIcons(void) for (i = 0; i < MAX_MON_MOVES; i++) { if (summary->moves[i] != MOVE_NONE) - SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[summary->moves[i]].contestCategory, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); + SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(summary->moves[i]), 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); else SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE); } @@ -4078,7 +4074,7 @@ static void SetContestMoveTypeIcons(void) static void SetNewMoveTypeIcon(void) { - u32 type = gMovesInfo[sMonSummaryScreen->newMove].type; + u32 type = GetMoveType(sMonSummaryScreen->newMove); struct Pokemon *mon = &sMonSummaryScreen->currentMon; if (P_SHOW_DYNAMIC_TYPES) @@ -4096,7 +4092,7 @@ static void SetNewMoveTypeIcon(void) } else { - SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[sMonSummaryScreen->newMove].contestCategory, 85, 96, SPRITE_ARR_ID_TYPE + 4); + SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(sMonSummaryScreen->newMove), 85, 96, SPRITE_ARR_ID_TYPE + 4); } } } diff --git a/src/rom_header_gf.c b/src/rom_header_gf.c index 1074a86bf8..c55535003c 100644 --- a/src/rom_header_gf.c +++ b/src/rom_header_gf.c @@ -1,10 +1,11 @@ #include "global.h" -#include "data.h" -#include "pokemon_icon.h" -#include "decoration.h" #include "battle_main.h" +#include "data.h" +#include "decoration.h" #include "item.h" +#include "move.h" #include "pokeball.h" +#include "pokemon_icon.h" // The purpose of this struct is for outside applications to be // able to access parts of the ROM or its save file, like a public API. diff --git a/src/scrcmd.c b/src/scrcmd.c index fe6ed4a316..d3104f6b43 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -29,6 +29,7 @@ #include "main.h" #include "menu.h" #include "money.h" +#include "move.h" #include "mystery_event_script.h" #include "palette.h" #include "party_menu.h" diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index 020094389a..fc248435a9 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -487,12 +487,49 @@ void ScrCmd_createmon(struct ScriptContext *ctx) u8 speedEv = PARSE_FLAG(8, 0); u8 spAtkEv = PARSE_FLAG(9, 0); u8 spDefEv = PARSE_FLAG(10, 0); - u8 hpIv = PARSE_FLAG(11, Random() % (MAX_PER_STAT_IVS + 1)); - u8 atkIv = PARSE_FLAG(12, Random() % (MAX_PER_STAT_IVS + 1)); - u8 defIv = PARSE_FLAG(13, Random() % (MAX_PER_STAT_IVS + 1)); - u8 speedIv = PARSE_FLAG(14, Random() % (MAX_PER_STAT_IVS + 1)); - u8 spAtkIv = PARSE_FLAG(15, Random() % (MAX_PER_STAT_IVS + 1)); - u8 spDefIv = PARSE_FLAG(16, Random() % (MAX_PER_STAT_IVS + 1)); + u8 hpIv = Random() % (MAX_PER_STAT_IVS + 1); + u8 atkIv = Random() % (MAX_PER_STAT_IVS + 1); + u8 defIv = Random() % (MAX_PER_STAT_IVS + 1); + u8 speedIv = Random() % (MAX_PER_STAT_IVS + 1); + u8 spAtkIv = Random() % (MAX_PER_STAT_IVS + 1); + u8 spDefIv = Random() % (MAX_PER_STAT_IVS + 1); + + // Perfect IV calculation + u32 i; + u8 availableIVs[NUM_STATS]; + u8 selectedIvs[NUM_STATS]; + if (gSpeciesInfo[species].perfectIVCount != 0) + { + // Initialize a list of IV indices. + for (i = 0; i < NUM_STATS; i++) + availableIVs[i] = i; + + // Select the IVs that will be perfected. + for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++) + { + u8 index = Random() % (NUM_STATS - i); + selectedIvs[i] = availableIVs[index]; + RemoveIVIndexFromList(availableIVs, index); + } + for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++) + { + switch (selectedIvs[i]) + { + case STAT_HP: hpIv = MAX_PER_STAT_IVS; break; + case STAT_ATK: atkIv = MAX_PER_STAT_IVS; break; + case STAT_DEF: defIv = MAX_PER_STAT_IVS; break; + case STAT_SPEED: speedIv = MAX_PER_STAT_IVS; break; + case STAT_SPATK: spAtkIv = MAX_PER_STAT_IVS; break; + case STAT_SPDEF: spDefIv = MAX_PER_STAT_IVS; break; + } + } + } + hpIv = PARSE_FLAG(11, hpIv); + atkIv = PARSE_FLAG(12, atkIv); + defIv = PARSE_FLAG(13, defIv); + speedIv = PARSE_FLAG(14, speedIv); + spAtkIv = PARSE_FLAG(15, spAtkIv); + spDefIv = PARSE_FLAG(16, spDefIv); u16 move1 = PARSE_FLAG(17, MOVE_NONE); u16 move2 = PARSE_FLAG(18, MOVE_NONE); u16 move3 = PARSE_FLAG(19, MOVE_NONE); diff --git a/src/shop.c b/src/shop.c index 224e9beed9..1a10e0d028 100644 --- a/src/shop.c +++ b/src/shop.c @@ -21,6 +21,7 @@ #include "menu.h" #include "menu_helpers.h" #include "money.h" +#include "move.h" #include "overworld.h" #include "palette.h" #include "party_menu.h" diff --git a/src/start_menu.c b/src/start_menu.c index 0c364bb07d..004403e659 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -44,6 +44,8 @@ #include "trainer_card.h" #include "window.h" #include "union_room.h" +#include "dexnav.h" +#include "wild_encounter.h" #include "constants/battle_frontier.h" #include "constants/rgb.h" #include "constants/songs.h" @@ -65,6 +67,7 @@ enum MENU_ACTION_RETIRE_FRONTIER, MENU_ACTION_PYRAMID_BAG, MENU_ACTION_DEBUG, + MENU_ACTION_DEXNAV, }; // Save status @@ -106,6 +109,7 @@ static bool8 StartMenuLinkModePlayerNameCallback(void); static bool8 StartMenuBattlePyramidRetireCallback(void); static bool8 StartMenuBattlePyramidBagCallback(void); static bool8 StartMenuDebugCallback(void); +static bool8 StartMenuDexNavCallback(void); // Menu callbacks static bool8 SaveStartCallback(void); @@ -200,6 +204,7 @@ static const struct MenuAction sStartMenuItems[] = [MENU_ACTION_RETIRE_FRONTIER] = {gText_MenuRetire, {.u8_void = StartMenuBattlePyramidRetireCallback}}, [MENU_ACTION_PYRAMID_BAG] = {gText_MenuBag, {.u8_void = StartMenuBattlePyramidBagCallback}}, [MENU_ACTION_DEBUG] = {sText_MenuDebug, {.u8_void = StartMenuDebugCallback}}, + [MENU_ACTION_DEXNAV] = {gText_MenuDexNav, {.u8_void = StartMenuDexNavCallback}}, }; static const struct BgTemplate sBgTemplates_LinkBattleSave[] = @@ -324,22 +329,20 @@ static void AddStartMenuAction(u8 action) } static void BuildNormalStartMenu(void) -{ +{ if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE) - { AddStartMenuAction(MENU_ACTION_POKEDEX); - } + + if (FLAG_SYS_DEXNAV_GET != 0 && FlagGet(FLAG_SYS_DEXNAV_GET)) + AddStartMenuAction(MENU_ACTION_DEXNAV); + if (FlagGet(FLAG_SYS_POKEMON_GET) == TRUE) - { AddStartMenuAction(MENU_ACTION_POKEMON); - } AddStartMenuAction(MENU_ACTION_BAG); if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE) - { AddStartMenuAction(MENU_ACTION_POKENAV); - } AddStartMenuAction(MENU_ACTION_PLAYER); AddStartMenuAction(MENU_ACTION_SAVE); @@ -638,7 +641,10 @@ static bool8 HandleStartMenuInput(void) if (GetNationalPokedexCount(FLAG_GET_SEEN) == 0) return FALSE; } - + if (sCurrentStartMenuActions[sStartMenuCursorPos] == MENU_ACTION_DEXNAV + && MapHasNoEncounterData()) + return FALSE; + gMenuCallback = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void; if (gMenuCallback != StartMenuSaveCallback @@ -663,7 +669,7 @@ static bool8 HandleStartMenuInput(void) return FALSE; } -static bool8 StartMenuPokedexCallback(void) +bool8 StartMenuPokedexCallback(void) { if (!gPaletteFade.active) { @@ -1485,3 +1491,9 @@ void AppendToList(u8 *list, u8 *pos, u8 newEntry) list[*pos] = newEntry; (*pos)++; } + +static bool8 StartMenuDexNavCallback(void) +{ + CreateTask(Task_OpenDexNavFromStartMenu, 0); + return TRUE; +} diff --git a/src/strings.c b/src/strings.c index fb3c96eb9d..37feea0da0 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1023,6 +1023,7 @@ const u8 gText_MenuOption[] = _("OPTION"); const u8 gText_MenuExit[] = _("EXIT"); const u8 gText_MenuRetire[] = _("RETIRE"); const u8 gText_MenuRest[] = _("REST"); +const u8 gText_MenuDexNav[] = _("DEXNAV"); const u8 gText_SafariBallStock[] = _("SAFARI BALLS\nStock: {STR_VAR_1}"); const u8 gText_BattlePyramidFloor[] = _("Battle Pyramid\n{STR_VAR_1}"); const u8 gText_Floor1[] = _("Floor 1"); diff --git a/src/text_window.c b/src/text_window.c index efd087977e..a1bae0d123 100644 --- a/src/text_window.c +++ b/src/text_window.c @@ -82,6 +82,9 @@ static const struct TilesPal sWindowFrames[WINDOW_FRAMES_COUNT] = {sTextWindowFrame20_Gfx, sTextWindowFrame20_Pal} }; +static const u16 sTextWindowDexNavFrame[] = INCBIN_U16("graphics/text_window/dexnav_pal.gbapal"); +static const struct TilesPal sDexNavWindowFrame = {gTextWindowFrame1_Gfx, sTextWindowDexNavFrame}; + // code const struct TilesPal *GetWindowFrameTilesPal(u8 id) { @@ -202,3 +205,9 @@ void LoadUserWindowBorderGfxOnBg(u8 bg, u16 destOffset, u8 palOffset) LoadBgTiles(bg, sWindowFrames[gSaveBlock2Ptr->optionsWindowFrameType].tiles, 0x120, destOffset); LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, palOffset, PLTT_SIZE_4BPP); } + +void LoadDexNavWindowGfx(u8 windowId, u16 destOffset, u8 palOffset) +{ + LoadBgTiles(GetWindowAttribute(windowId, WINDOW_BG), sDexNavWindowFrame.tiles, 0x120, destOffset); + LoadPalette(sDexNavWindowFrame.pal, palOffset, 32); +} diff --git a/src/trainer_hill.c b/src/trainer_hill.c index c89803ffb2..dd8ae78aa7 100644 --- a/src/trainer_hill.c +++ b/src/trainer_hill.c @@ -212,6 +212,14 @@ static const struct TrainerHillChallenge *const sChallengeData[NUM_TRAINER_HILL_ [HILL_MODE_EXPERT] = &sChallenge_Expert, }; +static const struct TrainerHillFloor *const sFloorData[NUM_TRAINER_HILL_MODES] = +{ + [HILL_MODE_NORMAL] = &sFloors_Normal[0], + [HILL_MODE_VARIETY] = &sFloors_Variety[0], + [HILL_MODE_UNIQUE] = &sFloors_Unique[0], + [HILL_MODE_EXPERT] = &sFloors_Expert[0], +}; + // Unused. static const u8 *const sFloorStrings[] = { @@ -357,20 +365,14 @@ void FreeTrainerHillBattleStruct(void) static void SetUpDataStruct(void) { #if FREE_TRAINER_HILL == FALSE - if (sHillData == NULL) - { - sHillData = AllocZeroed(sizeof(*sHillData)); - sHillData->floorId = gMapHeader.mapLayoutId - LAYOUT_TRAINER_HILL_1F; + if (sHillData != NULL) return; - // This copy depends on the floor data for each challenge being directly after the - // challenge header data, and for the field 'floors' in sHillData to come directly - // after the field 'challenge'. - // e.g. for HILL_MODE_NORMAL, it will copy sChallenge_Normal to sHillData->challenge and - // it will copy sFloors_Normal to sHillData->floors - CpuCopy32(sChallengeData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->challenge, sizeof(sHillData->challenge) + sizeof(sHillData->floors)); - TrainerHillDummy(); - } -#endif //FREE_TRAINER_HILL + sHillData = AllocZeroed(sizeof(*sHillData)); + sHillData->floorId = gMapHeader.mapLayoutId - LAYOUT_TRAINER_HILL_1F; + + CpuCopy32(sChallengeData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->challenge, sizeof(sHillData->challenge)); + CpuCopy32(sFloorData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->floors, sizeof(sHillData->floors)); +#endif // FREE_TRAINER_HILL } static void FreeDataStruct(void) diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 033eec56da..bd00e58fcd 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -186,7 +186,7 @@ static void FeebasSeedRng(u16 seed) } // LAND_WILD_COUNT -static u8 ChooseWildMonIndex_Land(void) +u8 ChooseWildMonIndex_Land(void) { u8 wildMonIndex = 0; bool8 swap = FALSE; @@ -227,7 +227,7 @@ static u8 ChooseWildMonIndex_Land(void) } // ROCK_WILD_COUNT / WATER_WILD_COUNT -static u8 ChooseWildMonIndex_WaterRock(void) +u8 ChooseWildMonIndex_WaterRock(void) { u8 wildMonIndex = 0; bool8 swap = FALSE; @@ -354,7 +354,7 @@ static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon, u8 wildMonIn } } -static u16 GetCurrentMapWildMonHeaderId(void) +u16 GetCurrentMapWildMonHeaderId(void) { u16 i; @@ -417,7 +417,7 @@ u8 PickWildMonNature(void) return Random() % NUM_NATURES; } -static void CreateWildMon(u16 species, u8 level) +void CreateWildMon(u16 species, u8 level) { bool32 checkCuteCharm = TRUE; @@ -1134,3 +1134,24 @@ bool8 StandardWildEncounter_Debug(void) DoStandardWildBattle_Debug(); return TRUE; } + +u8 ChooseHiddenMonIndex(void) +{ + #ifdef ENCOUNTER_CHANCE_HIDDEN_MONS_TOTAL + u8 rand = Random() % ENCOUNTER_CHANCE_HIDDEN_MONS_TOTAL; + + if (rand < ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_0) + return 0; + else if (rand >= ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_HIDDEN_MONS_SLOT_1) + return 1; + else + return 2; + #else + return 0xFF; + #endif +} + +bool32 MapHasNoEncounterData(void) +{ + return (GetCurrentMapWildMonHeaderId() == HEADER_NONE); +} diff --git a/test/battle/ability/aerilate.c b/test/battle/ability/aerilate.c index 4386034a59..efd6776d9b 100644 --- a/test/battle/ability/aerilate.c +++ b/test/battle/ability/aerilate.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); } SINGLE_BATTLE_TEST("Aerilate turns a Normal-type move into Flying-type move") diff --git a/test/battle/ability/anger_point.c b/test/battle/ability/anger_point.c index b803b40f3f..7e8be8cb33 100644 --- a/test/battle/ability/anger_point.c +++ b/test/battle/ability/anger_point.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a critical hit") { GIVEN { - ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit); + ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH)); PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); } OPPONENT(SPECIES_SNORUNT); } WHEN { @@ -23,8 +23,8 @@ SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack stage") { GIVEN { - ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit); - ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH)); + ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM); PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); } OPPONENT(SPECIES_SNORUNT) { Speed(1); } } WHEN { @@ -50,8 +50,8 @@ TO_DO_BATTLE_TEST("Anger Point triggers when a substitute takes the hit (Gen4)") SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit (Gen5+)") { GIVEN { - ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit); - ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE); + ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH)); + ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE); PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); } OPPONENT(SPECIES_SNORUNT) { Speed(1); } } WHEN { diff --git a/test/battle/ability/anger_shell.c b/test/battle/ability/anger_shell.c index cf28fad28c..0dde568ca0 100644 --- a/test/battle/ability/anger_shell.c +++ b/test/battle/ability/anger_shell.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% o PARAMETRIZE { hp = 254; activates = TRUE; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Anger Shell lowers Def/Sp.Def by 1 and raises Atk/Sp.Atk/Spd { u16 maxHp = 500; GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -73,7 +73,7 @@ SINGLE_BATTLE_TEST("Anger Shell activates after all hits from a multi-hit move") u32 j; u16 maxHp = 500; GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT); PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); } OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } // Always hits 5 times. } WHEN { diff --git a/test/battle/ability/battle_bond.c b/test/battle/ability/battle_bond.c index ef2b2753b3..f480367798 100644 --- a/test/battle/ability/battle_bond.c +++ b/test/battle/ability/battle_bond.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_WATER_GUN)); + ASSUME(!IsBattleMoveStatus(MOVE_WATER_GUN)); } SINGLE_BATTLE_TEST("Battle Bond does not transform species other than Greninja") diff --git a/test/battle/ability/beads_of_ruin.c b/test/battle/ability/beads_of_ruin.c index bbc71f6c2b..63b07d7c8a 100644 --- a/test/battle/ability/beads_of_ruin.c +++ b/test/battle/ability/beads_of_ruin.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY); } SINGLE_BATTLE_TEST("Beads of Ruin reduces Sp. Def if opposing mon's ability doesn't match") @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Beads of Ruin reduces Sp. Def if opposing mon's ability does SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { HP(1);} PLAYER(SPECIES_CHI_YU); OPPONENT(SPECIES_WOBBUFFET); @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battler SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1);} diff --git a/test/battle/ability/berserk.c b/test/battle/ability/berserk.c index 7d7f905170..c96bb260f8 100644 --- a/test/battle/ability/berserk.c +++ b/test/battle/ability/berserk.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Berserk activates only if the target had more than 50% of it PARAMETRIZE { hp = 254; activates = TRUE; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Berserk raises Sp.Atk by 1") { u16 maxHp = 500; GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(maxHp / 2 + 1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Berserk activates after all hits from a multi-hit move") u32 j; u16 maxHp = 500; GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT); PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(maxHp / 2 + 1); } OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } // Always hits 5 times. } WHEN { diff --git a/test/battle/ability/blaze.c b/test/battle/ability/blaze.c index a21d133359..c68c7466a1 100644 --- a/test/battle/ability/blaze.c +++ b/test/battle/ability/blaze.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage) PARAMETRIZE { hp = 99; } PARAMETRIZE { hp = 33; } GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/clear_body.c b/test/battle/ability/clear_body.c index 1e955431a1..89b89e96bf 100644 --- a/test/battle/ability/clear_body.c +++ b/test/battle/ability/clear_body.c @@ -58,13 +58,13 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke prevent stat st } GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2); - ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2); - ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); PLAYER(SPECIES_WOBBUFFET) OPPONENT(species) { Ability(ability); } } WHEN { @@ -91,7 +91,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke prevent Sticky PARAMETRIZE{ species = SPECIES_SOLGALEO; ability = ABILITY_FULL_METAL_BODY; } PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; } GIVEN { - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); PLAYER(SPECIES_WOBBUFFET) OPPONENT(SPECIES_WOBBUFFET) OPPONENT(species) { Ability(ability); } @@ -166,13 +166,13 @@ SINGLE_BATTLE_TEST("Mold Breaker, Teravolt, and Turboblaze ignore Clear Body and } GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2); - ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2); - ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); PLAYER(SPECIES_WOBBUFFET) { Ability(breakerAbility); } OPPONENT(species) { Ability(ability); } } WHEN { @@ -284,7 +284,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent A PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; burned = FALSE; } PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; burned = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) OPPONENT(species) { Ability(ability); if (burned) Status1(STATUS1_BURN); } } WHEN { @@ -306,8 +306,8 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent r PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } OPPONENT(SPECIES_WOBBUFFET) { Speed(3); } OPPONENT(species) { Speed(6); Ability(ability); } @@ -336,9 +336,9 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent T PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY); - ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY); + ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } OPPONENT(SPECIES_WOBBUFFET) { Speed(3); } OPPONENT(species) { Speed(6); Ability(ability); } @@ -378,7 +378,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent S GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE); - ASSUME(gMovesInfo[MOVE_AGILITY].effect == EFFECT_SPEED_UP_2); + ASSUME(GetMoveEffect(MOVE_AGILITY) == EFFECT_SPEED_UP_2); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } OPPONENT(species) { Speed(5); Ability(ability); } } WHEN { diff --git a/test/battle/ability/cloud_nine.c b/test/battle/ability/cloud_nine.c index fb87b7f2ba..613ea86e0a 100644 --- a/test/battle/ability/cloud_nine.c +++ b/test/battle/ability/cloud_nine.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but witho PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; } PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; } GIVEN { - ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM); + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/commander.c b/test/battle/ability/commander.c index 26f5574ba8..2220fb9ec2 100644 --- a/test/battle/ability/commander.c +++ b/test/battle/ability/commander.c @@ -175,7 +175,7 @@ DOUBLE_BATTLE_TEST("Commander prevents Red Card from working while Commander is DOUBLE_BATTLE_TEST("Commander Tatsugiri is not damaged by a double target move if Dondozo faints") { GIVEN { - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_DONDOZO) { HP(1); }; PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); } PLAYER(SPECIES_WYNAUT); @@ -308,7 +308,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri is still affected by Haze while controll DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Left Slot)") { GIVEN { - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); } PLAYER(SPECIES_DONDOZO); @@ -331,7 +331,7 @@ DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Left Slot)") DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Right Slot)") { GIVEN { - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); } PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_DONDOZO); @@ -380,7 +380,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not attack if Dondozo faints the sa DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when a commanded Dondozo faints") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS); + ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_DONDOZO) { HP(1); } PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); } @@ -402,7 +402,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when co PARAMETRIZE { targetPlayerRight = TRUE; } PARAMETRIZE { targetPlayerRight = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS); + ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS); PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); } PLAYER(SPECIES_DONDOZO); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/compound_eyes.c b/test/battle/ability/compound_eyes.c index 32fa1dda2e..338da6bf21 100644 --- a/test/battle/ability/compound_eyes.c +++ b/test/battle/ability/compound_eyes.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Compound Eyes raises accuracy") { PASSES_RANDOMLY(91, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER].accuracy == 70); + ASSUME(GetMoveAccuracy(MOVE_THUNDER) == 70); PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_COMPOUND_EYES); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -20,8 +20,8 @@ SINGLE_BATTLE_TEST("Compound Eyes does not affect OHKO moves") { PASSES_RANDOMLY(30, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_FISSURE].accuracy == 30); - ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO); + ASSUME(GetMoveAccuracy(MOVE_FISSURE) == 30); + ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO); PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_COMPOUND_EYES); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/contrary.c b/test/battle/ability/contrary.c index 56eb6abf65..3c9c3e6dff 100644 --- a/test/battle/ability/contrary.c +++ b/test/battle/ability/contrary.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Contrary raises Attack when Intimidated in a single battle", s16 damage) @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Contrary raises stats after using a move which would normall PARAMETRIZE { ability = ABILITY_TANGLED_FEET; } GIVEN { ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); - ASSUME(gMovesInfo[MOVE_OVERHEAT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_OVERHEAT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SPINDA) { Ability(ability); } } WHEN { @@ -126,7 +126,7 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal PARAMETRIZE { ability = ABILITY_CONTRARY; } PARAMETRIZE { ability = ABILITY_TANGLED_FEET; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_WOBBUFFET) { Defense(102); } OPPONENT(SPECIES_SPINDA) { Ability(ability); Attack(100); } } WHEN { @@ -163,7 +163,7 @@ SINGLE_BATTLE_TEST("Contrary raises a stat after using a move which would normal PARAMETRIZE { ability = ABILITY_CONTRARY; } PARAMETRIZE { ability = ABILITY_TANGLED_FEET; } GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); PLAYER(SPECIES_WOBBUFFET) { Speed(3); } OPPONENT(SPECIES_SPINDA) { Ability(ability); Speed(2); } } WHEN { @@ -194,7 +194,7 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal PARAMETRIZE { ability = ABILITY_CONTRARY; } PARAMETRIZE { ability = ABILITY_TANGLED_FEET; } GIVEN { - ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SPINDA) { Ability(ability); } } WHEN { diff --git a/test/battle/ability/corrosion.c b/test/battle/ability/corrosion.c index 8addbd90fa..8541c21f27 100644 --- a/test/battle/ability/corrosion.c +++ b/test/battle/ability/corrosion.c @@ -30,8 +30,8 @@ SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Steel type with a sta PARAMETRIZE { move = MOVE_TOXIC; } GIVEN { - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_BELDUM); } WHEN { @@ -72,7 +72,7 @@ SINGLE_BATTLE_TEST("Corrosion can poison Poison- and Steel-type targets if it us PARAMETRIZE { heldItem = ITEM_TOXIC_ORB; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); ASSUME(gItemsInfo[ITEM_POISON_BARB].holdEffect == HOLD_EFFECT_POISON_POWER); ASSUME(gItemsInfo[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(heldItem); } @@ -110,8 +110,8 @@ SINGLE_BATTLE_TEST("If a Poison- or Steel-type Pokémon with Corrosion poisons a PARAMETRIZE { move = MOVE_TOXIC; } PARAMETRIZE { move = MOVE_POISON_POWDER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); } } WHEN { @@ -137,8 +137,8 @@ SINGLE_BATTLE_TEST("Corrosion cannot bypass moves that prevent poisoning such as PARAMETRIZE { move = MOVE_TOXIC; } PARAMETRIZE { move = MOVE_POISON_POWDER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -159,8 +159,8 @@ SINGLE_BATTLE_TEST("Corrosion cannot bypass abilities that prevent poisoning suc PARAMETRIZE { move = MOVE_TOXIC; } PARAMETRIZE { move = MOVE_POISON_POWDER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); } } WHEN { @@ -181,9 +181,9 @@ SINGLE_BATTLE_TEST("Corrosion allows the Pokémon with the ability to poison a S PARAMETRIZE { move = MOVE_TOXIC; } PARAMETRIZE { move = MOVE_POISON_POWDER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_BELDUM); } WHEN { @@ -205,9 +205,9 @@ SINGLE_BATTLE_TEST("Corrosion's effect is lost if the move used by the Pokémon PARAMETRIZE { move = MOVE_TOXIC; } PARAMETRIZE { move = MOVE_POISON_POWDER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/cud_chew.c b/test/battle/ability/cud_chew.c index 297635c9f3..9ac5593474 100644 --- a/test/battle/ability/cud_chew.c +++ b/test/battle/ability/cud_chew.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Cud Chew will activate Kee Berry effect again on the next tu { GIVEN { ASSUME(gItemsInfo[ITEM_KEE_BERRY].holdEffect == HOLD_EFFECT_KEE_BERRY); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_TAUROS_PALDEA_COMBAT) { Ability(ABILITY_CUD_CHEW); Item(ITEM_KEE_BERRY); } } WHEN { @@ -28,8 +28,8 @@ SINGLE_BATTLE_TEST("Cud Chew will activate Oran Berry effect again on the next t GIVEN { ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_TAUROS_PALDEA_COMBAT) { MaxHP(60); HP(60); Ability(ABILITY_CUD_CHEW); Item(ITEM_ORAN_BERRY); } } WHEN { diff --git a/test/battle/ability/cute_charm.c b/test/battle/ability/cute_charm.c index e6eee0ae08..55e64b3226 100644 --- a/test/battle/ability/cute_charm.c +++ b/test/battle/ability/cute_charm.c @@ -7,15 +7,15 @@ SINGLE_BATTLE_TEST("Cute Charm inflicts infatuation on contact") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); } OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); } } WHEN { TURN { MOVE(player, move); } TURN { MOVE(player, move); } } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ABILITY_CUTE_CHARM); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_INFATUATION, player); MESSAGE("The opposing Clefairy's Cute Charm infatuated Wobbuffet!"); @@ -51,7 +51,7 @@ SINGLE_BATTLE_TEST("Cute Charm triggers 30% of the time") PASSES_RANDOMLY(3, 10, RNG_CUTE_CHARM); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); } OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); } } WHEN { diff --git a/test/battle/ability/damp.c b/test/battle/ability/damp.c index b567293aa0..1088a7a17e 100644 --- a/test/battle/ability/damp.c +++ b/test/battle/ability/damp.c @@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from self") SINGLE_BATTLE_TEST("Damp prevents damage from Aftermath") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_PARAS) { Ability(ABILITY_DAMP); } OPPONENT(SPECIES_VOLTORB) { Ability(ABILITY_AFTERMATH); HP(1); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/dancer.c b/test/battle/ability/dancer.c index 5519ac3222..657a126470 100644 --- a/test/battle/ability/dancer.c +++ b/test/battle/ability/dancer.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Dancer can copy a dance move immediately after it was used and allow the user of Dancer to still use its move") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUIVER_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_QUIVER_DANCE)); PLAYER(SPECIES_WOBBUFFET) OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } } WHEN { @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Dancer can copy a dance move immediately after it was used a SINGLE_BATTLE_TEST("Dancer can copy Teeter Dance") { GIVEN { - ASSUME(gMovesInfo[MOVE_TEETER_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_TEETER_DANCE)); PLAYER(SPECIES_WOBBUFFET) OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Item(ITEM_LUM_BERRY); } } WHEN { @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Dancer can copy Teeter Dance") DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targets") { GIVEN { - ASSUME(gMovesInfo[MOVE_TEETER_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_TEETER_DANCE)); ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); PLAYER(SPECIES_WOBBUFFET) PLAYER(SPECIES_WYNAUT) { Item(ITEM_LUM_BERRY); } @@ -57,7 +57,7 @@ DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targe DOUBLE_BATTLE_TEST("Dancer triggers from slowest to fastest") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Speed(10); } PLAYER(SPECIES_WYNAUT) { Speed(50); } OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Speed(20); } @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Dancer doesn't trigger if the original user flinches") { GIVEN { ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100)); - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); PLAYER(SPECIES_WOBBUFFET) OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } } WHEN { @@ -102,7 +102,7 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches") { GIVEN { ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100)); - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Speed(10); } PLAYER(SPECIES_WYNAUT) { Speed(5); } OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Speed(20); } @@ -130,8 +130,8 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches") SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated") { GIVEN { - ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE); - ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE); + ASSUME(IsDanceMove(MOVE_REVELATION_DANCE)); + ASSUME(GetMoveEffect(MOVE_REVELATION_DANCE) == EFFECT_REVELATION_DANCE); PLAYER(SPECIES_TANGROWTH); OPPONENT(SPECIES_ORICORIO_BAILE); } WHEN { @@ -149,8 +149,8 @@ SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated") DOUBLE_BATTLE_TEST("Dancer doesn't trigger on a snatched move") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); - ASSUME(gMovesInfo[MOVE_SNATCH].effect == EFFECT_SNATCH); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); + ASSUME(GetMoveEffect(MOVE_SNATCH) == EFFECT_SNATCH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ORICORIO); @@ -173,9 +173,9 @@ DOUBLE_BATTLE_TEST("Dancer doesn't trigger on a snatched move") DOUBLE_BATTLE_TEST("Dancer triggers on Instructed dance moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].instructBanned == FALSE); - ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); + ASSUME(!IsMoveInstructBanned(MOVE_DRAGON_DANCE)); + ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ORICORIO); @@ -200,9 +200,9 @@ DOUBLE_BATTLE_TEST("Dancer triggers on Instructed dance moves") DOUBLE_BATTLE_TEST("Dancer-called move doesn't update move to be Instructed") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); - ASSUME(gMovesInfo[MOVE_TACKLE].instructBanned == FALSE); - ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); + ASSUME(!IsMoveInstructBanned(MOVE_TACKLE)); + ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ORICORIO); @@ -228,8 +228,8 @@ DOUBLE_BATTLE_TEST("Dancer-called move doesn't update move to be Instructed") DOUBLE_BATTLE_TEST("Dancer doesn't call a move that didn't execute due to Powder") { GIVEN { - ASSUME(gMovesInfo[MOVE_FIERY_DANCE].danceMove == TRUE); - ASSUME(gMovesInfo[MOVE_FIERY_DANCE].type == TYPE_FIRE); + ASSUME(IsDanceMove(MOVE_FIERY_DANCE)); + ASSUME(GetMoveType(MOVE_FIERY_DANCE) == TYPE_FIRE); PLAYER(SPECIES_VOLCARONA); PLAYER(SPECIES_ORICORIO); OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/ability/dazzling.c b/test/battle/ability/dazzling.c index 9eedb56a49..cc77e9a3bd 100644 --- a/test/battle/ability/dazzling.c +++ b/test/battle/ability/dazzling.c @@ -4,7 +4,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority > 0); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) > 0); } DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail protect the user from priority moves") diff --git a/test/battle/ability/defeatist.c b/test/battle/ability/defeatist.c index d2866d6f30..18d8186a50 100644 --- a/test/battle/ability/defeatist.c +++ b/test/battle/ability/defeatist.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_ECHOED_VOICE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_ECHOED_VOICE) == DAMAGE_CATEGORY_SPECIAL); } SINGLE_BATTLE_TEST("Defeatist halves Attack when HP <= 50%", s16 damage) diff --git a/test/battle/ability/defiant.c b/test/battle/ability/defiant.c index 9b767b8323..b1bd102453 100644 --- a/test/battle/ability/defiant.c +++ b/test/battle/ability/defiant.c @@ -277,7 +277,7 @@ SINGLE_BATTLE_TEST("Defiant activates before White Herb") SINGLE_BATTLE_TEST("Defiant activates for each stat that is lowered") { GIVEN { - ASSUME(gMovesInfo[MOVE_TICKLE].effect == EFFECT_TICKLE); + ASSUME(GetMoveEffect(MOVE_TICKLE) == EFFECT_TICKLE); PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/desolate_land.c b/test/battle/ability/desolate_land.c index 18fe76b0c9..5bf1358503 100644 --- a/test/battle/ability/desolate_land.c +++ b/test/battle/ability/desolate_land.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_WATER_GUN)); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(!IsBattleMoveStatus(MOVE_WATER_GUN)); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); } SINGLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves") @@ -32,9 +32,9 @@ SINGLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves") DOUBLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves and prints the message only once with moves hitting multiple targets") { GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_SURF)); - ASSUME(gMovesInfo[MOVE_SURF].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(!IsBattleMoveStatus(MOVE_SURF)); + ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_GROUDON) {Item(ITEM_RED_ORB); {Speed(5);}} PLAYER(SPECIES_WOBBUFFET) {Speed(5);} OPPONENT(SPECIES_WOBBUFFET) {Speed(10);} diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c index 3a8df70be5..b1d854f0cf 100644 --- a/test/battle/ability/disguise.c +++ b/test/battle/ability/disguise.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_AERIAL_ACE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing to its busted form") @@ -28,7 +28,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing SINGLE_BATTLE_TEST("Disguised Mimikyu takes no damage from a confusion hit and changes to its busted form") { GIVEN { - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -69,7 +69,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu's Air Balloon will pop upon changing to it SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from secondary damage without breaking the disguise") { GIVEN { - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_WOBBUFFET); @@ -138,7 +138,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker") SINGLE_BATTLE_TEST("Disguised Mimikyu's types revert back to Ghost/Fairy when Disguise is broken") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHADOW_CLAW].type == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_SHADOW_CLAW) == TYPE_GHOST); PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -158,7 +158,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu's types revert back to Ghost/Fairy when Di SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Batton Passed") { GIVEN { - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_WOBBUFFET); @@ -173,3 +173,19 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Ba ABILITY_POPUP(player, ABILITY_DISGUISE); } } + +SINGLE_BATTLE_TEST("Disguise does not break from a teammate's Wish") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_WISH) == EFFECT_WISH); + PLAYER(SPECIES_JIRACHI); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); HP(219); MaxHP(220); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_WISH); } + TURN { SWITCH(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WISH, player); + NOT ABILITY_POPUP(player, ABILITY_DISGUISE); + } +} diff --git a/test/battle/ability/download.c b/test/battle/ability/download.c index 480f0bf10e..eec380e421 100644 --- a/test/battle/ability/download.c +++ b/test/battle/ability/download.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_TRI_ATTACK].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TRI_ATTACK) == DAMAGE_CATEGORY_SPECIAL); } SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp. Def", s16 damage) @@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Download doesn't activate if target hasn't been sent out yet PARAMETRIZE { ability = ABILITY_TRACE; } PARAMETRIZE { ability = ABILITY_DOWNLOAD; } GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { Speed(100); } PLAYER(SPECIES_PORYGON) { Ability(ability); Defense(400); SpDefense(300); Speed(300); Attack(100); } OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); } diff --git a/test/battle/ability/dragons_maw.c b/test/battle/ability/dragons_maw.c index 401c4244c8..d7e1ebd793 100644 --- a/test/battle/ability/dragons_maw.c +++ b/test/battle/ability/dragons_maw.c @@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Dragon's Maw increases Dragon-type move damage", s16 damage) PARAMETRIZE { move = MOVE_DRAGON_BREATH; ability = ABILITY_DRAGONS_MAW; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_DRAGON); - ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].type == TYPE_DRAGON); - ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].type == TYPE_DRAGON); - ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_DRAGON); + ASSUME(GetMoveType(MOVE_DRAGON_CLAW) == TYPE_DRAGON); + ASSUME(GetMoveType(MOVE_DRAGON_BREATH) == TYPE_DRAGON); + ASSUME(GetMoveCategory(MOVE_DRAGON_CLAW) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_DRAGON_BREATH) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_REGIDRAGO) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/dry_skin.c b/test/battle/ability/dry_skin.c index 5709a58a94..95a0cd8fa8 100644 --- a/test/battle/ability/dry_skin.c +++ b/test/battle/ability/dry_skin.c @@ -39,8 +39,8 @@ SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%" PARAMETRIZE { ability = ABILITY_EFFECT_SPORE; } PARAMETRIZE { ability = ABILITY_DRY_SKIN; } GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_EMBER].power == 40); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMovePower(MOVE_EMBER) == 40); ASSUME(gSpeciesInfo[SPECIES_PARASECT].types[0] == TYPE_BUG); ASSUME(gSpeciesInfo[SPECIES_PARASECT].types[1] == TYPE_GRASS); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC); @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%" SINGLE_BATTLE_TEST("Dry Skin heals 25% when hit by water type moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Dry Skin heals 25% when hit by water type moves") SINGLE_BATTLE_TEST("Dry Skin does not activate if protected") { GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -92,8 +92,8 @@ SINGLE_BATTLE_TEST("Dry Skin does not activate if protected") SINGLE_BATTLE_TEST("Dry Skin is only triggered once on multi strike moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveType(MOVE_WATER_SHURIKEN) == TYPE_WATER); + ASSUME(GetMoveEffect(MOVE_WATER_SHURIKEN) == EFFECT_MULTI_HIT); PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Dry Skin prevents Absorb Bulb and Luminous Moss from activat PARAMETRIZE { item = ITEM_ABSORB_BULB; } PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; } GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/earth_eater.c b/test/battle/ability/earth_eater.c index 2e6ae6dab5..c30b9674f5 100644 --- a/test/battle/ability/earth_eater.c +++ b/test/battle/ability/earth_eater.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Earth Eater heals 25% when hit by ground type moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_MUD_SLAP].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_MUD_SLAP) == TYPE_GROUND); PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Earth Eater heals 25% when hit by ground type moves") SINGLE_BATTLE_TEST("Earth Eater does not activate if protected") { GIVEN { - ASSUME(gMovesInfo[MOVE_MUD_SLAP].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_MUD_SLAP) == TYPE_GROUND); PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -35,8 +35,8 @@ SINGLE_BATTLE_TEST("Earth Eater does not activate if protected") SINGLE_BATTLE_TEST("Earth Eater activates on status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].type == TYPE_GROUND); - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveType(MOVE_SAND_ATTACK) == TYPE_GROUND); + ASSUME(GetMoveCategory(MOVE_SAND_ATTACK) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/effect_spore.c b/test/battle/ability/effect_spore.c index 49750c4797..06ac84f39a 100644 --- a/test/battle/ability/effect_spore.c +++ b/test/battle/ability/effect_spore.c @@ -8,15 +8,15 @@ SINGLE_BATTLE_TEST("Effect Spore only inflicts status on contact") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } } WHEN { TURN { MOVE(player, move, WITH_RNG(RNG_EFFECT_SPORE, 1)); } TURN {} } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player); MESSAGE("Wobbuffet was poisoned by the opposing Breloom's Effect Spore!"); @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes poison 9% of the time") PASSES_RANDOMLY(9, 100, RNG_EFFECT_SPORE); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } } WHEN { @@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes paralysis 10% of the time") PASSES_RANDOMLY(10, 100, RNG_EFFECT_SPORE); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } } WHEN { @@ -75,7 +75,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes sleep 11% of the time") PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } } WHEN { diff --git a/test/battle/ability/electric_surge.c b/test/battle/ability/electric_surge.c new file mode 100644 index 0000000000..3509f1c687 --- /dev/null +++ b/test/battle/ability/electric_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electric Surge creates Electric Terrain when entering the battle"); diff --git a/test/battle/ability/electromorphosis.c b/test/battle/ability/electromorphosis.c index 0f0ac1c39a..38a61f4c29 100644 --- a/test/battle/ability/electromorphosis.c +++ b/test/battle/ability/electromorphosis.c @@ -10,12 +10,12 @@ SINGLE_BATTLE_TEST("Electromorphosis sets up Charge when hit by any move") PARAMETRIZE {move = MOVE_GUST; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); - ASSUME(!IS_MOVE_STATUS(MOVE_GUST)); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(!IS_MOVE_STATUS(MOVE_THUNDER_SHOCK)); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_GUST)); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(!IsBattleMoveStatus(MOVE_THUNDER_SHOCK)); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); PLAYER(SPECIES_BELLIBOLT) { Ability(ABILITY_ELECTROMORPHOSIS); Speed(10); } OPPONENT(SPECIES_WOBBUFFET) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed. diff --git a/test/battle/ability/flame_body.c b/test/battle/ability/flame_body.c index b8fa850b65..95afa862c1 100644 --- a/test/battle/ability/flame_body.c +++ b/test/battle/ability/flame_body.c @@ -7,14 +7,14 @@ SINGLE_BATTLE_TEST("Flame Body inflicts burn on contact") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); } } WHEN { TURN { MOVE(player, move); } } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ABILITY_FLAME_BODY); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, player); MESSAGE("The opposing Magmar's Flame Body burned Wobbuffet!"); @@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Flame Body triggers 30% of the time") PASSES_RANDOMLY(3, 10, RNG_FLAME_BODY); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); } } WHEN { diff --git a/test/battle/ability/flower_gift.c b/test/battle/ability/flower_gift.c index 5ceb26c5c1..4f09e84a9a 100644 --- a/test/battle/ability/flower_gift.c +++ b/test/battle/ability/flower_gift.c @@ -96,7 +96,7 @@ DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies b PARAMETRIZE { sunny = FALSE; } PARAMETRIZE { sunny = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_CHERRIM_OVERCAST) { Ability(ABILITY_FLOWER_GIFT); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -131,7 +131,7 @@ DOUBLE_BATTLE_TEST("Flower Gift increases the Sp. Def of Cherrim and its allies PARAMETRIZE { sunny = FALSE; } PARAMETRIZE { sunny = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_HYPER_VOICE) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_CHERRIM_OVERCAST) { Ability(ABILITY_FLOWER_GIFT); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/fluffy.c b/test/battle/ability/fluffy.c index 30a8b83182..5c51ec2627 100644 --- a/test/battle/ability/fluffy.c +++ b/test/battle/ability/fluffy.c @@ -3,11 +3,11 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_FIRE_PUNCH].makesContact); - ASSUME(gMovesInfo[MOVE_FIRE_PUNCH].type == TYPE_FIRE); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(MoveMakesContact(MOVE_FIRE_PUNCH)); + ASSUME(GetMoveType(MOVE_FIRE_PUNCH) == TYPE_FIRE); } SINGLE_BATTLE_TEST("Fluffy halves damage taken from moves that make direct contact", s16 damage) diff --git a/test/battle/ability/frisk.c b/test/battle/ability/frisk.c index 28bd477a35..e6d7f275fb 100644 --- a/test/battle/ability/frisk.c +++ b/test/battle/ability/frisk.c @@ -42,7 +42,7 @@ DOUBLE_BATTLE_TEST("Frisk triggers for player in a Double Battle after switching PARAMETRIZE { target = playerRight; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_POUND)); + ASSUME(!IsBattleMoveStatus(MOVE_POUND)); PLAYER(SPECIES_WOBBUFFET) { HP(1); } PLAYER(SPECIES_WOBBUFFET) { HP(1); } PLAYER(SPECIES_FURRET) { Ability(ABILITY_FRISK); }; @@ -65,7 +65,7 @@ DOUBLE_BATTLE_TEST("Frisk triggers for opponent in a Double Battle after switchi PARAMETRIZE { target = opponentRight; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_POUND)); + ASSUME(!IsBattleMoveStatus(MOVE_POUND)); PLAYER(SPECIES_WYNAUT) { Item(ITEM_POTION); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET) { HP(1); } diff --git a/test/battle/ability/gale_wings.c b/test/battle/ability/gale_wings.c index eff4589649..df8f025326 100644 --- a/test/battle/ability/gale_wings.c +++ b/test/battle/ability/gale_wings.c @@ -1,20 +1,22 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP") +SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP (Gen 7+)") { - u16 hp; - PARAMETRIZE { hp = 100; } - PARAMETRIZE { hp = 99; } + u32 hp, config; + PARAMETRIZE { hp = 100; config = GEN_7; } + PARAMETRIZE { hp = 99; config = GEN_7; } + PARAMETRIZE { hp = 100; config = GEN_6; } + PARAMETRIZE { hp = 99; config = GEN_6; } GIVEN { - ASSUME(B_GALE_WINGS >= GEN_7); - ASSUME(gMovesInfo[MOVE_AERIAL_ACE].type == TYPE_FLYING); + WITH_CONFIG(GEN_CONFIG_GALE_WINGS, config); + ASSUME(GetMoveType(MOVE_AERIAL_ACE) == TYPE_FLYING); PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(hp); MaxHP(100); Speed(1);} OPPONENT(SPECIES_WOBBUFFET) { Speed(100);}; } WHEN { TURN { MOVE(player, MOVE_AERIAL_ACE); } } SCENE { - if (hp == 100) { + if (hp == 100 || config <= GEN_6) { MESSAGE("Talonflame used Aerial Ace!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); } @@ -31,9 +33,8 @@ SINGLE_BATTLE_TEST("Gale Wings only grants priority to Flying-type moves") PARAMETRIZE { move = MOVE_AERIAL_ACE; } PARAMETRIZE { move = MOVE_FLARE_BLITZ; } GIVEN { - ASSUME(B_GALE_WINGS >= GEN_7); - ASSUME(gMovesInfo[MOVE_AERIAL_ACE].type == TYPE_FLYING); - ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_AERIAL_ACE) == TYPE_FLYING); + ASSUME(GetMoveType(MOVE_FLARE_BLITZ) == TYPE_FIRE); PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(100); MaxHP(100); Speed(1);} OPPONENT(SPECIES_WOBBUFFET) { Speed(100);}; } WHEN { @@ -58,12 +59,11 @@ SINGLE_BATTLE_TEST("Gale Wings doesn't increase priority of Flying-type Natural PARAMETRIZE { move = MOVE_JUDGMENT; heldItem = ITEM_SKY_PLATE; } PARAMETRIZE { move = MOVE_HIDDEN_POWER; heldItem = ITEM_NONE; } GIVEN { - ASSUME(B_GALE_WINGS >= GEN_7); - ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); - ASSUME(gMovesInfo[MOVE_JUDGMENT].effect == EFFECT_CHANGE_TYPE_ON_ITEM); + ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT); + ASSUME(GetMoveEffect(MOVE_JUDGMENT) == EFFECT_CHANGE_TYPE_ON_ITEM); // IV combinations sourced from https://www.smogon.com/forums/threads/hidden-power-iv-combinations.78083/ - ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER); - ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST); + ASSUME(GetMoveEffect(MOVE_HIDDEN_POWER) == EFFECT_HIDDEN_POWER); + ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST); ASSUME(gItemsInfo[ITEM_SKY_PLATE].holdEffect == HOLD_EFFECT_PLATE); ASSUME(gItemsInfo[ITEM_SKY_PLATE].secondaryId == TYPE_FLYING); ASSUME(gNaturalGiftTable[ITEM_TO_BERRY(ITEM_LUM_BERRY)].type == TYPE_FLYING); diff --git a/test/battle/ability/galvanize.c b/test/battle/ability/galvanize.c index 1da82e861d..6de5675b6a 100644 --- a/test/battle/ability/galvanize.c +++ b/test/battle/ability/galvanize.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); } SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric") @@ -29,9 +29,9 @@ SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type move PARAMETRIZE { move = MOVE_MULTI_ATTACK; } GIVEN { - ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER); - ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL); - ASSUME(gMovesInfo[MOVE_MULTI_ATTACK].effect == EFFECT_CHANGE_TYPE_ON_ITEM); + ASSUME(GetMoveEffect(MOVE_HIDDEN_POWER) == EFFECT_HIDDEN_POWER); + ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL); + ASSUME(GetMoveEffect(MOVE_MULTI_ATTACK) == EFFECT_CHANGE_TYPE_ON_ITEM); PLAYER(SPECIES_KRABBY); OPPONENT(SPECIES_GEODUDE_ALOLA) { Ability(ABILITY_GALVANIZE); } } WHEN { diff --git a/test/battle/ability/good_as_gold.c b/test/battle/ability/good_as_gold.c index 40561ee767..fc6c6bc8c4 100644 --- a/test/battle/ability/good_as_gold.c +++ b/test/battle/ability/good_as_gold.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Good as Gold protects from status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveCategory(MOVE_TOXIC) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); } } WHEN { @@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Good as Gold protects from status moves") SINGLE_BATTLE_TEST("Good as Gold doesn't protect the user from it's own moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_NASTY_PLOT].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveCategory(MOVE_NASTY_PLOT) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); } } WHEN { @@ -37,8 +37,8 @@ SINGLE_BATTLE_TEST("Good as Gold doesn't protect the user from it's own moves") SINGLE_BATTLE_TEST("Good as Gold doesn't protect from moves that target the field") { GIVEN { - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].target == MOVE_TARGET_OPPONENTS_FIELD); + ASSUME(GetMoveCategory(MOVE_STEALTH_ROCK) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveTarget(MOVE_STEALTH_ROCK) == MOVE_TARGET_OPPONENTS_FIELD); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); } } WHEN { @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Good as Gold doesn't protect from moves that target the fiel DOUBLE_BATTLE_TEST("Good as Gold protects from partner's status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_HELPING_HAND].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveCategory(MOVE_HELPING_HAND) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); } diff --git a/test/battle/ability/grassy_surge.c b/test/battle/ability/grassy_surge.c new file mode 100644 index 0000000000..ccdb471d9f --- /dev/null +++ b/test/battle/ability/grassy_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Grassy Surge creates Grassy Terrain when entering the battle"); diff --git a/test/battle/ability/grim_neigh.c b/test/battle/ability/grim_neigh.c index 6e0073f955..c58487722b 100644 --- a/test/battle/ability/grim_neigh.c +++ b/test/battle/ability/grim_neigh.c @@ -7,7 +7,7 @@ DOUBLE_BATTLE_TEST("Grim Neigh raises Sp. Attack by one stage after directly cau PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; } PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; } GIVEN { - ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(species) { Ability(ability); } PLAYER(SPECIES_SNORUNT) { HP(1); } OPPONENT(SPECIES_GLALIE) { HP(1); } @@ -81,7 +81,7 @@ DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move th PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; } GIVEN { - ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(species) { Ability(ability); } PLAYER(SPECIES_ABRA) { HP(1); } OPPONENT(SPECIES_GLALIE); diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c index 189702a4be..72e826b252 100644 --- a/test/battle/ability/gulp_missile.c +++ b/test/battle/ability/gulp_missile.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - // ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL); + // ASSUME(GetMoveCategory(MOVE_AERIAL_ACE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("(Gulp Missile) If base Cramorant hits target with Surf it transforms into Gulping form if max HP is over 1/2") @@ -167,7 +167,7 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant Gulping lowers defense PARAMETRIZE { ability = ABILITY_INFILTRATOR; } PARAMETRIZE { ability = ABILITY_CLEAR_BODY; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); Item(ITEM_ROCKY_HELMET); } OPPONENT(SPECIES_DRAGAPULT) { Ability(ability); } } WHEN { diff --git a/test/battle/ability/harvest.c b/test/battle/ability/harvest.c index 03e13b394e..92e7517df5 100644 --- a/test/battle/ability/harvest.c +++ b/test/battle/ability/harvest.c @@ -5,7 +5,7 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP); ASSUME(I_SITRUS_BERRY_HEAL >= GEN_4); - ASSUME(gMovesInfo[MOVE_SUNNY_DAY].effect == EFFECT_SUNNY_DAY); + ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY); } SINGLE_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn") @@ -61,7 +61,7 @@ SINGLE_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Loc SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in") { GIVEN { - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); + ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } OPPONENT(SPECIES_WOBBUFFET); @@ -80,7 +80,7 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and b SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } } WHEN { @@ -97,7 +97,7 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling") SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift") { GIVEN { - ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); + ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } } WHEN { @@ -209,7 +209,7 @@ DOUBLE_BATTLE_TEST("Harvest order is affected by speed") SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another Pokémon") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } } WHEN { @@ -226,7 +226,7 @@ SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another P SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from another Pokémon") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK); PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); } OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); } } WHEN { @@ -245,7 +245,7 @@ SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from anothe SINGLE_BATTLE_TEST("Harvest can only restore the newest berry consumed that was transferred from another Pokémon instead of its original Berry") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK); ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP); PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); } OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); Item(ITEM_APICOT_BERRY); } diff --git a/test/battle/ability/hyper_cutter.c b/test/battle/ability/hyper_cutter.c index a688da2531..7bd5504965 100644 --- a/test/battle/ability/hyper_cutter.c +++ b/test/battle/ability/hyper_cutter.c @@ -29,7 +29,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter prevents intimidate") SINGLE_BATTLE_TEST("Hyper Cutter prevents Attack stage reduction from moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } } WHEN { @@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter prevents Attack stage reduction from moves") SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack reduction from burn") { GIVEN { - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP); + ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } } WHEN { @@ -59,7 +59,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack reduction from burn") SINGLE_BATTLE_TEST("Hyper Cutter is ignored by Mold Breaker") { GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } } WHEN { @@ -97,8 +97,8 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack stage reduction from mov SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Topsy-Turvy") { GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); - ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } } WHEN { @@ -116,7 +116,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Topsy-Turvy") SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Spectral Thief from resetting positive Attack stage changes") { GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } @@ -135,8 +135,8 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Spectral Thief from resetting p SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent receiving negative Attack stage changes from Baton Pass") { GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); } diff --git a/test/battle/ability/ice_body.c b/test/battle/ability/ice_body.c index 3f278a50cd..07890d52f2 100644 --- a/test/battle/ability/ice_body.c +++ b/test/battle/ability/ice_body.c @@ -2,8 +2,8 @@ #include "test/battle.h" ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); } SINGLE_BATTLE_TEST("Ice Body prevents damage from hail") diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c index 22b67a7a53..a462b80265 100644 --- a/test/battle/ability/ice_face.c +++ b/test/battle/ability/ice_face.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_EISCUE); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -18,8 +18,8 @@ SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noi SINGLE_BATTLE_TEST("Ice Face does not block special moves, Eiscue stays in Ice Face form") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_EMBER) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_EISCUE); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -35,9 +35,9 @@ SINGLE_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face PARAMETRIZE { move = MOVE_SNOWSCAPE; } PARAMETRIZE { move = MOVE_HAIL; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); PLAYER(SPECIES_EISCUE); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -60,9 +60,9 @@ SINGLE_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while h PARAMETRIZE { move = MOVE_SNOWSCAPE; } PARAMETRIZE { move = MOVE_HAIL; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); PLAYER(SPECIES_EISCUE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -86,9 +86,9 @@ SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face f PARAMETRIZE { move = MOVE_SNOWSCAPE; } PARAMETRIZE { move = MOVE_HAIL; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); PLAYER(SPECIES_EISCUE) { HP(1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -105,7 +105,7 @@ SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face f SINGLE_BATTLE_TEST("Ice Face form change persists after switching out") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_EISCUE) { HP(1); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -123,7 +123,7 @@ SINGLE_BATTLE_TEST("Ice Face form change persists after switching out") SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_EISCUE) { HP(1); } OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); } } WHEN { @@ -142,9 +142,9 @@ SINGLE_BATTLE_TEST("Ice Face is not restored if hail or snow and Eiscue are alre PARAMETRIZE { move = MOVE_SNOWSCAPE; } PARAMETRIZE { move = MOVE_HAIL; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); PLAYER(SPECIES_EISCUE); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/ability/ice_scales.c b/test/battle/ability/ice_scales.c index fd262147a5..37c5aa0944 100644 --- a/test/battle/ability/ice_scales.c +++ b/test/battle/ability/ice_scales.c @@ -12,10 +12,10 @@ SINGLE_BATTLE_TEST("Ice Scales halves the damage from special moves", s16 damage PARAMETRIZE { ability = ABILITY_SHIELD_DUST; move = MOVE_TACKLE; } PARAMETRIZE { ability = ABILITY_ICE_SCALES; move = MOVE_TACKLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_PSYSHOCK].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_PSYSHOCK].effect == EFFECT_PSYSHOCK); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_PSYSHOCK) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveEffect(MOVE_PSYSHOCK) == EFFECT_PSYSHOCK); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_FROSMOTH) { Ability(ability); } } WHEN { diff --git a/test/battle/ability/immunity.c b/test/battle/ability/immunity.c index 2fa90686c5..92e32d31f3 100644 --- a/test/battle/ability/immunity.c +++ b/test/battle/ability/immunity.c @@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Immunity prevents Poison Sting poison") SINGLE_BATTLE_TEST("Immunity prevents Toxic bad poison") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); } } WHEN { @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Immunity prevents Toxic bad poison") SINGLE_BATTLE_TEST("Immunity prevents Toxic Spikes poison") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); } diff --git a/test/battle/ability/innards_out.c b/test/battle/ability/innards_out.c index 5837b98d1f..5613ff72f6 100644 --- a/test/battle/ability/innards_out.c +++ b/test/battle/ability/innards_out.c @@ -14,8 +14,8 @@ SINGLE_BATTLE_TEST("Innards Out deal dmg on fainting equal to the amount of dmg PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(70); SpAttack(1000); } OPPONENT(SPECIES_WOBBUFFET); - ASSUME(!IS_MOVE_STATUS(MOVE_PSYCHIC)); - ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC)); + ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL); } WHEN { TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); if (hp == 100) { SEND_OUT(opponent, 1); } } } SCENE { @@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Innards Out does not trigger after Gastro Acid has been used PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); - ASSUME(!IS_MOVE_STATUS(MOVE_PSYCHIC)); - ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID); + ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC)); + ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID); } WHEN { TURN { MOVE(opponent, MOVE_GASTRO_ACID); } TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); } @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Innards Out does not damage Magic Guard Pokemon") PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); } - ASSUME(!IS_MOVE_STATUS(MOVE_PSYCHIC)); + ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC)); } WHEN { TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); } } SCENE { diff --git a/test/battle/ability/insomnia.c b/test/battle/ability/insomnia.c index 3098ce6d3f..65a69cbbc3 100644 --- a/test/battle/ability/insomnia.c +++ b/test/battle/ability/insomnia.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Insomnia prevents sleep") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Insomnia prevents sleep") SINGLE_BATTLE_TEST("Insomnia prevents yawn") { GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("Insomnia prevents yawn") SINGLE_BATTLE_TEST("Insomnia prevents rest") { GIVEN { - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); HP(1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/intimidate.c b/test/battle/ability/intimidate.c index e0f97d5bda..2553c2755f 100644 --- a/test/battle/ability/intimidate.c +++ b/test/battle/ability/intimidate.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after switch out", s16 damage) @@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after KO", s16 DOUBLE_BATTLE_TEST("Intimidate doesn't activate on an empty field in a double battle") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { HP(1); } PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); } @@ -271,9 +271,9 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutral PARAMETRIZE { move = MOVE_HEALING_WISH; } PARAMETRIZE { move = MOVE_BATON_PASS; } GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } PLAYER(SPECIES_WOBBUFFET) { HP(1); } OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } @@ -302,9 +302,9 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutral GIVEN { ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON); ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK); - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR); - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Item(item); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } @@ -333,7 +333,7 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutral SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - fainted") { GIVEN { - ASSUME(gMovesInfo[MOVE_FELL_STINGER].effect == EFFECT_FELL_STINGER); + ASSUME(GetMoveEffect(MOVE_FELL_STINGER) == EFFECT_FELL_STINGER); PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); HP(1); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } diff --git a/test/battle/ability/intrepid_sword.c b/test/battle/ability/intrepid_sword.c index 68300fb229..58fd9883eb 100644 --- a/test/battle/ability/intrepid_sword.c +++ b/test/battle/ability/intrepid_sword.c @@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Intrepid Sword activates when it's no longer effected by Neu SINGLE_BATTLE_TEST("Intrepid Sword and Dauntless Shield both can be Skill Swapped and active their effects on the Skill Swap user") { GIVEN { - ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); } OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); } diff --git a/test/battle/ability/keen_eye.c b/test/battle/ability/keen_eye.c index b047ec988f..0268477ded 100644 --- a/test/battle/ability/keen_eye.c +++ b/test/battle/ability/keen_eye.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].accuracy == 100); - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveAccuracy(MOVE_TACKLE) == 100); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); ASSUME(B_ILLUMINATE_EFFECT >= GEN_9); } @@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye ignore target's evasi PASSES_RANDOMLY(100, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP); + ASSUME(GetMoveEffect(MOVE_DOUBLE_TEAM) == EFFECT_EVASION_UP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { @@ -78,7 +78,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye are ignored by Mold B PARAMETRIZE { speciesOpponent = SPECIES_URSALUNA_BLOODMOON; abilityOpponent = ABILITY_MINDS_EYE; } } - PASSES_RANDOMLY(gMovesInfo[MOVE_TACKLE].accuracy * 3 / 4, 100, RNG_ACCURACY); + PASSES_RANDOMLY(GetMoveAccuracy(MOVE_TACKLE) * 3 / 4, 100, RNG_ACCURACY); GIVEN { PLAYER(speciesPlayer) { Ability(abilityPlayer); } OPPONENT(speciesOpponent) { Ability(abilityOpponent); } @@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent Topsy-T PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } GIVEN { - ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP); - ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY); + ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP); + ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { @@ -141,7 +141,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent receivi PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; } GIVEN { - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } @@ -173,7 +173,7 @@ SINGLE_BATTLE_TEST("Keen Eye & Gen9+ Illuminate don't prevent Spectral Thief fro PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP); + ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP); ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } diff --git a/test/battle/ability/leaf_guard.c b/test/battle/ability/leaf_guard.c index af113f1bb6..e04881ecb4 100644 --- a/test/battle/ability/leaf_guard.c +++ b/test/battle/ability/leaf_guard.c @@ -11,10 +11,10 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun") PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; } // PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; } // Pointless since you can't freeze in sunlight anyway GIVEN { - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP); - ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE); - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP); + ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun") { GIVEN { ASSUME(B_LEAF_GUARD_PREVENTS_REST >= GEN_5); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); HP(100); MaxHP(200); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/lightning_rod.c b/test/battle/ability/lightning_rod.c index c719ee145d..4a90a8573c 100644 --- a/test/battle/ability/lightning_rod.c +++ b/test/battle/ability/lightning_rod.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the Sp. Attack [Gen5+]") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); } } WHEN { @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to target the Pokémon with this Ability.") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); } diff --git a/test/battle/ability/liquid_ooze.c b/test/battle/ability/liquid_ooze.c new file mode 100644 index 0000000000..05b78dce73 --- /dev/null +++ b/test/battle/ability/liquid_ooze.c @@ -0,0 +1,112 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Liquid Ooze causes Absorb users to lose HP instead of heal") +{ + s16 damage; + s16 healed; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + } WHEN { + TURN { MOVE(player, MOVE_ABSORB); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + } THEN { + EXPECT_MUL_EQ(damage, Q_4_12(0.5), healed); + } +} + +SINGLE_BATTLE_TEST("Liquid Ooze causes Leech Seed users to lose HP instead of heal") +{ + s16 damage; + s16 healed; + + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + } WHEN { + TURN { MOVE(player, MOVE_LEECH_SEED); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + } THEN { + EXPECT_EQ(damage, healed); + } +} + +DOUBLE_BATTLE_TEST("Liquid Ooze causes Matcha Gatcha users to lose HP instead of heal") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB); + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft); + HP_BAR(opponentLeft); + HP_BAR(playerLeft); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + MESSAGE("Wobbuffet fainted!"); + } +} + +DOUBLE_BATTLE_TEST("Liquid Ooze will faint Matcha Gatcha users if it deals enough damage") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB); + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft); + HP_BAR(opponentLeft); + HP_BAR(playerLeft); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + MESSAGE("Wobbuffet fainted!"); + } +} + +SINGLE_BATTLE_TEST("Liquid Ooze causes Strength Sap users to lose HP instead of heal") +{ + s16 lostHp; + s32 atkStat; + + PARAMETRIZE { atkStat = 100; } + PARAMETRIZE { atkStat = 490; } // Checks that attacker can faint with no problems. + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Attack(atkStat); Ability(ABILITY_LIQUID_OOZE); } + } WHEN { + TURN { MOVE(player, MOVE_STRENGTH_SAP); if (atkStat == 490) { SEND_OUT(player, 1); } } + } SCENE { + MESSAGE("Wobbuffet used Strength Sap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("The opposing Wobbuffet's Attack fell!"); + ABILITY_POPUP(opponent, ABILITY_LIQUID_OOZE); + HP_BAR(player, captureDamage: &lostHp); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + if (atkStat >= 490) { + MESSAGE("Wobbuffet fainted!"); + SEND_IN_MESSAGE("Wobbuffet"); + } + } THEN { + EXPECT_EQ(lostHp, atkStat); + } +} + +TO_DO_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP instead of heal (Gen 3-4"); +TO_DO_BATTLE_TEST("Liquid Ooze causes Dream Eater users to lose HP instead of heal (Gen 5+"); diff --git a/test/battle/ability/magic_bounce.c b/test/battle/ability/magic_bounce.c index a643b22824..2731a21fed 100644 --- a/test/battle/ability/magic_bounce.c +++ b/test/battle/ability/magic_bounce.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } } WHEN { @@ -22,8 +22,8 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back status moves") SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); - ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); + ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } } WHEN { @@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves") SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass Types") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); PLAYER(SPECIES_ODDISH); OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } @@ -59,8 +59,8 @@ SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass T DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting both foes at two foes") { GIVEN { - ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); - ASSUME(gMovesInfo[MOVE_LEER].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveTarget(MOVE_LEER) == MOVE_TARGET_BOTH); PLAYER(SPECIES_ABRA); PLAYER(SPECIES_KADABRA); OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } @@ -92,7 +92,7 @@ DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting foes field") battlerTwo = SPECIES_ESPEON; abilityBattlerTwo = ABILITY_MAGIC_BOUNCE; } GIVEN { - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].target == MOVE_TARGET_OPPONENTS_FIELD); + ASSUME(GetMoveTarget(MOVE_STEALTH_ROCK) == MOVE_TARGET_OPPONENTS_FIELD); PLAYER(SPECIES_ABRA); PLAYER(SPECIES_KADABRA); OPPONENT(battlerOne) { Ability(abilityBattlerOne); } @@ -118,7 +118,7 @@ DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting foes field") SINGLE_BATTLE_TEST("Magic Bounce bounced back status moves can not be bounced back by Magic Bounce") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } } WHEN { diff --git a/test/battle/ability/magic_guard.c b/test/battle/ability/magic_guard.c index 5579652265..8941fb2130 100644 --- a/test/battle/ability/magic_guard.c +++ b/test/battle/ability/magic_guard.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Magic Guard prevents recoil damage to the user") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil == 33); + ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) == 33); PLAYER(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -15,3 +15,32 @@ SINGLE_BATTLE_TEST("Magic Guard prevents recoil damage to the user") NOT HP_BAR(player); } } + +SINGLE_BATTLE_TEST("Magic Guard ignores immobilization that can be caused by paralysis") +{ + if (B_MAGIC_GUARD >= GEN_4) + PASSES_RANDOMLY(1, 1, RNG_PARALYSIS); + else + PASSES_RANDOMLY(75, 100, RNG_PARALYSIS); + GIVEN { + PLAYER(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); Status1(STATUS1_PARALYSIS);} + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } +} + +SINGLE_BATTLE_TEST("Magic Guard does not ignore speed stat changes caused by paralysis") +{ + GIVEN { + PLAYER(SPECIES_CLEFABLE) { Speed(100); Ability(ABILITY_MAGIC_GUARD); Status1(STATUS1_PARALYSIS);} + OPPONENT(SPECIES_WOBBUFFET) { Speed(99); } + } WHEN { + TURN { } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } +} diff --git a/test/battle/ability/magician.c b/test/battle/ability/magician.c index 14e553a763..f622ac07df 100644 --- a/test/battle/ability/magician.c +++ b/test/battle/ability/magician.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life { GIVEN { ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB); - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_DELPHOX) { Ability(ABILITY_MAGICIAN); Item(ITEM_NONE); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); } } WHEN { diff --git a/test/battle/ability/mimicry.c b/test/battle/ability/mimicry.c new file mode 100644 index 0000000000..fbdb5cf98a --- /dev/null +++ b/test/battle/ability/mimicry.c @@ -0,0 +1,72 @@ +#include "global.h" +#include "test/battle.h" + +static const u16 terrainData[][2] = +{ + { MOVE_ELECTRIC_TERRAIN, TYPE_ELECTRIC, }, + { MOVE_PSYCHIC_TERRAIN, TYPE_PSYCHIC, }, + { MOVE_GRASSY_TERRAIN, TYPE_GRASS, }, + { MOVE_MISTY_TERRAIN, TYPE_FAIRY, }, +}; + +SINGLE_BATTLE_TEST("Mimicry changes the battler's type based on Terrain") +{ + u32 j; + u32 terrainMove = MOVE_NONE; + u32 terrainType = TYPE_NONE; + + for (j = 0; j < ARRAY_COUNT(terrainData); j++) + PARAMETRIZE { terrainMove = terrainData[j][0]; terrainType = terrainData[j][1]; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } + } WHEN { + TURN { MOVE(player, terrainMove); } + } SCENE { + ABILITY_POPUP(opponent); + switch (terrainMove) + { + case MOVE_ELECTRIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Electric!"); break; + case MOVE_PSYCHIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Psychic!"); break; + case MOVE_GRASSY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Grass!"); break; + case MOVE_MISTY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Fairy!"); break; + } + } THEN { + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], terrainType); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], terrainType); + } +} + +SINGLE_BATTLE_TEST("Mimicry restores the battler's types when terrain is removed by Steel Roller and Ice Spinner") +{ + u32 j; + u32 terrainMove = MOVE_NONE; + u32 removeTerrainMove = MOVE_NONE; + + for (j = 0; j < ARRAY_COUNT(terrainData); j++) + { + PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainData[j][0]; } + PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainData[j][0]; } + } + + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[0] == TYPE_GROUND); + ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } + } WHEN { + TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } + } SCENE { + switch (terrainMove) + { + case MOVE_ELECTRIC_TERRAIN: MESSAGE("The electricity disappeared from the battlefield."); break; + case MOVE_PSYCHIC_TERRAIN: MESSAGE("The weirdness disappeared from the battlefield!"); break; + case MOVE_GRASSY_TERRAIN: MESSAGE("The grass disappeared from the battlefield."); break; + case MOVE_MISTY_TERRAIN: MESSAGE("The mist disappeared from the battlefield."); break; + } + } THEN { + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GROUND); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], TYPE_STEEL); + } +} diff --git a/test/battle/ability/minds_eye.c b/test/battle/ability/minds_eye.c index bf50fa0e2e..59c81746c7 100644 --- a/test/battle/ability/minds_eye.c +++ b/test/battle/ability/minds_eye.c @@ -48,7 +48,7 @@ AI_SINGLE_BATTLE_TEST("AI doesn't use accuracy-lowering moves if it knows that t for (j = MOVE_NONE + 1; j < MOVES_COUNT; j++) { - if (gMovesInfo[j].effect == EFFECT_ACCURACY_DOWN || gMovesInfo[j].effect == EFFECT_ACCURACY_DOWN_2) { + if (GetMoveEffect(j) == EFFECT_ACCURACY_DOWN || GetMoveEffect(j) == EFFECT_ACCURACY_DOWN_2) { PARAMETRIZE { moveAI = j; abilityAI = ABILITY_SWIFT_SWIM; } PARAMETRIZE { moveAI = j; abilityAI = ABILITY_MOLD_BREAKER; } } diff --git a/test/battle/ability/mirror_armor.c b/test/battle/ability/mirror_armor.c index 288fe72334..5aa2b55ef3 100644 --- a/test/battle/ability/mirror_armor.c +++ b/test/battle/ability/mirror_armor.c @@ -171,8 +171,8 @@ DOUBLE_BATTLE_TEST("Mirror Armor lowers Speed of the partner Pokemon after Court { KNOWN_FAILING; GIVEN { - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); - ASSUME(gMovesInfo[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); } diff --git a/test/battle/ability/misty_surge.c b/test/battle/ability/misty_surge.c new file mode 100644 index 0000000000..229d26c3ba --- /dev/null +++ b/test/battle/ability/misty_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Misty Surge creates Misty Terrain when entering the battle"); diff --git a/test/battle/ability/moxie.c b/test/battle/ability/moxie.c index d6c7d11d9d..35ae64d164 100644 --- a/test/battle/ability/moxie.c +++ b/test/battle/ability/moxie.c @@ -8,7 +8,7 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh raises Attack by one stage after direct PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(species) { Ability(ability); } PLAYER(SPECIES_SNORUNT) { HP(1); } OPPONENT(SPECIES_GLALIE) { HP(1); } @@ -84,7 +84,7 @@ SINGLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger when already at maximu PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM); PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_SNORUNT) { HP(1); } OPPONENT(SPECIES_SNORUNT); @@ -123,7 +123,7 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the sa PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(species) { Ability(ability); } PLAYER(SPECIES_ABRA) { HP(1); } OPPONENT(SPECIES_GLALIE); diff --git a/test/battle/ability/mummy.c b/test/battle/ability/mummy.c index 74461ec2ee..f03e453e5c 100644 --- a/test/battle/ability/mummy.c +++ b/test/battle/ability/mummy.c @@ -10,14 +10,14 @@ SINGLE_BATTLE_TEST("Mummy/Lingering Aroma replace the attacker's ability on cont PARAMETRIZE { move = MOVE_AQUA_JET; ability = ABILITY_LINGERING_AROMA; species = SPECIES_OINKOLOGNE; } PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_LINGERING_AROMA; species = SPECIES_OINKOLOGNE; } GIVEN { - ASSUME(gMovesInfo[MOVE_AQUA_JET].makesContact); - ASSUME(!gMovesInfo[MOVE_WATER_GUN].makesContact); + ASSUME(MoveMakesContact(MOVE_AQUA_JET)); + ASSUME(!MoveMakesContact(MOVE_WATER_GUN)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { TURN { MOVE(player, move); } } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ability); if (ability == ABILITY_MUMMY) MESSAGE("Wobbuffet acquired Mummy!"); @@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Mummy and Lingering Aroma don't replace each other") PARAMETRIZE { ability1 = ABILITY_MUMMY; species1 = SPECIES_YAMASK; ability2 = ABILITY_LINGERING_AROMA; species2 = SPECIES_OINKOLOGNE; } PARAMETRIZE { ability1 = ability2 = ABILITY_LINGERING_AROMA; species1 = species2 = SPECIES_OINKOLOGNE; } GIVEN { - ASSUME(gMovesInfo[MOVE_AQUA_JET].makesContact); + ASSUME(MoveMakesContact(MOVE_AQUA_JET)); PLAYER(species1) { Ability(ability1); Speed(2); } OPPONENT(species2) { Ability(ability2); Speed(1); } } WHEN { diff --git a/test/battle/ability/neuroforce.c b/test/battle/ability/neuroforce.c index 88af00b722..bd40982d02 100644 --- a/test/battle/ability/neuroforce.c +++ b/test/battle/ability/neuroforce.c @@ -10,8 +10,8 @@ SINGLE_BATTLE_TEST("Neuroforce increases the strength of super-effective moves b PARAMETRIZE { ability = ABILITY_NEUROFORCE; move = MOVE_TACKLE; } PARAMETRIZE { ability = ABILITY_KLUTZ; move = MOVE_TACKLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST); - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); PLAYER(SPECIES_NECROZMA_ULTRA) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/oblivious.c b/test/battle/ability/oblivious.c index 70bf941923..3ac979a271 100644 --- a/test/battle/ability/oblivious.c +++ b/test/battle/ability/oblivious.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Infatuation") { GIVEN { - ASSUME(gMovesInfo[MOVE_ATTRACT].effect == EFFECT_ATTRACT); + ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT); PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); } } WHEN { @@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Infatuation") SINGLE_BATTLE_TEST("Oblivious prevents Captivate") { GIVEN { - ASSUME(gMovesInfo[MOVE_CAPTIVATE].effect == EFFECT_CAPTIVATE); + ASSUME(GetMoveEffect(MOVE_CAPTIVATE) == EFFECT_CAPTIVATE); PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); } } WHEN { @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Captivate") SINGLE_BATTLE_TEST("Oblivious prevents Taunt") { GIVEN { - ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT); + ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT); ASSUME(B_OBLIVIOUS_TAUNT >= GEN_6); PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/opportunist.c b/test/battle/ability/opportunist.c index 662d442dbc..2abd483466 100644 --- a/test/battle/ability/opportunist.c +++ b/test/battle/ability/opportunist.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Opportunist only copies foe's positive stat changes in a turn", s16 damage) diff --git a/test/battle/ability/overcoat.c b/test/battle/ability/overcoat.c index b73f098e78..96f3ffcb08 100644 --- a/test/battle/ability/overcoat.c +++ b/test/battle/ability/overcoat.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Overcoat blocks powder and spore moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT); } } WHEN { diff --git a/test/battle/ability/overgrow.c b/test/battle/ability/overgrow.c index 0bc2d7cdd5..3ba7790093 100644 --- a/test/battle/ability/overgrow.c +++ b/test/battle/ability/overgrow.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Overgrow boosts Grass-type moves in a pinch", s16 damage) PARAMETRIZE { hp = 99; } PARAMETRIZE { hp = 33; } GIVEN { - ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS); + ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); PLAYER(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); MaxHP(99); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/own_tempo.c b/test/battle/ability/own_tempo.c index 4b3c42053b..a6dd8c4591 100644 --- a/test/battle/ability/own_tempo.c +++ b/test/battle/ability/own_tempo.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes { GIVEN { ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; } WHEN { @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes SINGLE_BATTLE_TEST("Own Tempo prevents confusion from moves by the opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; } WHEN { @@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Own Tempo is ignored by Mold Breaker") { KNOWN_FAILING; // Ideally the func CanBeConfused should be split into AttackerCanBeConfused and TargetCanBeConfused or we do it in the same func but have a check for when battlerAtk == battlerDef GIVEN { - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; } WHEN { @@ -77,7 +77,7 @@ SINGLE_BATTLE_TEST("Own Tempo cures confusion obtained from an opponent with Mol { KNOWN_FAILING; GIVEN { - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }; OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; } WHEN { @@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("Own Tempo cures confusion obtained from an opponent with Mol SINGLE_BATTLE_TEST("Own Tempo cures confusion if it's obtained via Skill Swap") { GIVEN { - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE); - ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/parental_bond.c b/test/battle/ability/parental_bond.c index a1614a8ffc..29f137f6af 100644 --- a/test/battle/ability/parental_bond.c +++ b/test/battle/ability/parental_bond.c @@ -4,9 +4,9 @@ SINGLE_BATTLE_TEST("Parental Bond converts Tackle into a two-strike move") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_TACKLE].strikeCount < 2); - ASSUME(gMovesInfo[MOVE_TACKLE].effect == EFFECT_HIT); + ASSUME(GetMoveCategory(MOVE_TACKLE) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveStrikeCount(MOVE_TACKLE) < 2); + ASSUME(GetMoveEffect(MOVE_TACKLE) == EFFECT_HIT); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -27,8 +27,8 @@ SINGLE_BATTLE_TEST("Parental Bond converts Tackle into a two-strike move") SINGLE_BATTLE_TEST("Parental Bond does not convert a move with three or more strikes to a two-strike move") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].strikeCount == 3); + ASSUME(GetMoveCategory(MOVE_TRIPLE_KICK) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveStrikeCount(MOVE_TRIPLE_KICK) == 3); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -54,10 +54,10 @@ SINGLE_BATTLE_TEST("Parental Bond converts multi-target moves into a two-strike PARAMETRIZE { move = MOVE_ICY_WIND; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].strikeCount < 2); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_ICY_WIND].strikeCount < 2); - ASSUME(gMovesInfo[MOVE_ICY_WIND].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveStrikeCount(MOVE_EARTHQUAKE) < 2); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveStrikeCount(MOVE_ICY_WIND) < 2); + ASSUME(GetMoveTarget(MOVE_ICY_WIND) == MOVE_TARGET_BOTH); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -78,8 +78,8 @@ SINGLE_BATTLE_TEST("Parental Bond converts multi-target moves into a two-strike DOUBLE_BATTLE_TEST("Parental Bond does not convert multi-target moves into a two-strike move in Double Battles, even if it only damages one") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].strikeCount < 2); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveStrikeCount(MOVE_EARTHQUAKE) < 2); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); ASSUME(gSpeciesInfo[SPECIES_PIDGEY].types[1] == TYPE_FLYING); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } PLAYER(SPECIES_PIDGEY); @@ -109,8 +109,8 @@ SINGLE_BATTLE_TEST("Parental Bond-converted moves only hit once on Lightning Rod PARAMETRIZE { move = MOVE_THUNDERBOLT; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; type = TYPE_ELECTRIC; } PARAMETRIZE { move = MOVE_SURF; ability = ABILITY_STORM_DRAIN; species = SPECIES_LILEEP; type = TYPE_WATER; } GIVEN { - ASSUME(gMovesInfo[move].strikeCount < 2); - ASSUME(gMovesInfo[move].type == type); + ASSUME(GetMoveStrikeCount(move) < 2); + ASSUME(GetMoveType(move) == type); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(species) { Ability(ability); } } WHEN { @@ -137,8 +137,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil GIVEN { ASSUME(B_MULTI_HIT_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -163,8 +163,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil GIVEN { ASSUME(B_MULTI_HIT_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -190,8 +190,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil GIVEN { ASSUME(B_MULTI_HIT_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -218,8 +218,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil GIVEN { ASSUME(B_MULTI_HIT_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -242,8 +242,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil SINGLE_BATTLE_TEST("Parental Bond Smack Down effect triggers after 2nd hit") { GIVEN { - ASSUME(gMovesInfo[MOVE_SMACK_DOWN].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_SMACK_DOWN].strikeCount < 2); + ASSUME(GetMoveCategory(MOVE_SMACK_DOWN) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveStrikeCount(MOVE_SMACK_DOWN) < 2); ASSUME(MoveHasAdditionalEffect(MOVE_SMACK_DOWN, MOVE_EFFECT_SMACK_DOWN)); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_SKARMORY); @@ -267,7 +267,7 @@ SINGLE_BATTLE_TEST("Parental Bond Snore strikes twice while asleep") { s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_SNORE].effect == EFFECT_SNORE); + ASSUME(GetMoveEffect(MOVE_SNORE) == EFFECT_SNORE); PLAYER(SPECIES_KANGASKHAN_MEGA) { Status1(STATUS1_SLEEP); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -289,7 +289,7 @@ SINGLE_BATTLE_TEST("Parental Bond Snore strikes twice while asleep") SINGLE_BATTLE_TEST("Parental Bond only triggers Dragon Tail's target switch out on the second hit") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/ability/pastel_veil.c b/test/battle/ability/pastel_veil.c index a6b6168547..686ca0ff85 100644 --- a/test/battle/ability/pastel_veil.c +++ b/test/battle/ability/pastel_veil.c @@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison") { KNOWN_FAILING; GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } } WHEN { @@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison") DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } @@ -70,7 +70,7 @@ DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner") SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } } WHEN { @@ -86,7 +86,7 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison") DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } @@ -104,7 +104,7 @@ DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner") SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } @@ -120,7 +120,7 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison") DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison on partner") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); } diff --git a/test/battle/ability/pickup.c b/test/battle/ability/pickup.c index a6dabb66cc..22db259399 100644 --- a/test/battle/ability/pickup.c +++ b/test/battle/ability/pickup.c @@ -120,7 +120,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item after its holder faints") SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if holder is replaced") { GIVEN { - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); + ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } OPPONENT(SPECIES_WOBBUFFET) { MaxHP(300); HP(151); Item(ITEM_SITRUS_BERRY); } @@ -202,7 +202,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item if the user eats it with Bug Bi SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restored it") { GIVEN { - ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE); + ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE); PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } } WHEN { @@ -222,7 +222,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restor SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } } WHEN { @@ -239,7 +239,7 @@ SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged") SINGLE_BATTLE_TEST("Pickup restores an item that was used by Natural Gift") { GIVEN { - ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); + ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT); PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } } WHEN { diff --git a/test/battle/ability/pixilate.c b/test/battle/ability/pixilate.c index 97c9c37a0c..44289769a6 100644 --- a/test/battle/ability/pixilate.c +++ b/test/battle/ability/pixilate.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); } SINGLE_BATTLE_TEST("Pixilate turns a Normal-type move into a Fairy-type move") diff --git a/test/battle/ability/poison_point.c b/test/battle/ability/poison_point.c index 9f9cd5e900..635698379c 100644 --- a/test/battle/ability/poison_point.c +++ b/test/battle/ability/poison_point.c @@ -7,15 +7,15 @@ SINGLE_BATTLE_TEST("Poison Point inflicts poison on contact") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); } } WHEN { TURN { MOVE(player, move); } TURN {} } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ABILITY_POISON_POINT); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player); MESSAGE("Wobbuffet was poisoned by the opposing Nidoran♂'s Poison Point!"); @@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Poison Point triggers 30% of the time") PASSES_RANDOMLY(3, 10, RNG_POISON_POINT); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); } } WHEN { diff --git a/test/battle/ability/poison_puppeteer.c b/test/battle/ability/poison_puppeteer.c index b8124b975b..d5c470ad37 100644 --- a/test/battle/ability/poison_puppeteer.c +++ b/test/battle/ability/poison_puppeteer.c @@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Poison Puppeteer confuses target if it was (badly) poisoned SINGLE_BATTLE_TEST("Poison Puppeteer does not trigger if poison is Toxic Spikes induced") { GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); PLAYER(SPECIES_PECHARUNT) { Ability(ABILITY_POISON_PUPPETEER); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/poison_touch.c b/test/battle/ability/poison_touch.c index 8fb4d243fb..530d361794 100644 --- a/test/battle/ability/poison_touch.c +++ b/test/battle/ability/poison_touch.c @@ -5,8 +5,8 @@ SINGLE_BATTLE_TEST("Poison Touch has a 30% chance to poison when attacking with { PASSES_RANDOMLY(3, 10, RNG_POISON_TOUCH); GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -27,15 +27,15 @@ SINGLE_BATTLE_TEST("Poison Touch only applies when using contact moves") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, move); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, move, player); - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(player, ABILITY_POISON_TOUCH); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); MESSAGE("The opposing Wobbuffet was poisoned by Grimer's Poison Touch!"); @@ -54,8 +54,8 @@ SINGLE_BATTLE_TEST("Poison Touch only applies when using contact moves") SINGLE_BATTLE_TEST("Poison Touch applies between multi-hit move hits") { GIVEN { - ASSUME(gMovesInfo[MOVE_ARM_THRUST].effect == EFFECT_MULTI_HIT); - ASSUME(gMovesInfo[MOVE_ARM_THRUST].makesContact); + ASSUME(GetMoveEffect(MOVE_ARM_THRUST) == EFFECT_MULTI_HIT); + ASSUME(MoveMakesContact(MOVE_ARM_THRUST)); ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN); PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_PECHA_BERRY); }; diff --git a/test/battle/ability/prankster.c b/test/battle/ability/prankster.c index c569506729..cf297214d9 100644 --- a/test/battle/ability/prankster.c +++ b/test/battle/ability/prankster.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(gSpeciesInfo[SPECIES_UMBREON].types[0] == TYPE_DARK); - ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveCategory(MOVE_CONFUSE_RAY) == DAMAGE_CATEGORY_STATUS); } SINGLE_BATTLE_TEST("Prankster-affected moves don't affect Dark-type Pokémon") @@ -135,7 +135,7 @@ SINGLE_BATTLE_TEST("Prankster is blocked by Quick Guard in Gen5+") DOUBLE_BATTLE_TEST("Prankster-affected moves that target all Pokémon are successful regardless of the presence of Dark-type Pokémon") { GIVEN { - ASSUME(gMovesInfo[MOVE_CAPTIVATE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_CAPTIVATE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_ILLUMISE) { Ability(ABILITY_PRANKSTER); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_UMBREON); diff --git a/test/battle/ability/primordial_sea.c b/test/battle/ability/primordial_sea.c index 01ed892874..e895d8ba48 100644 --- a/test/battle/ability/primordial_sea.c +++ b/test/battle/ability/primordial_sea.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_EMBER)); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(!IsBattleMoveStatus(MOVE_EMBER)); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); } SINGLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves") @@ -32,9 +32,9 @@ SINGLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves") DOUBLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves and prints the message only once with moves hitting multiple targets") { GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_ERUPTION)); - ASSUME(gMovesInfo[MOVE_ERUPTION].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_ERUPTION].target == MOVE_TARGET_BOTH); + ASSUME(!IsBattleMoveStatus(MOVE_ERUPTION)); + ASSUME(GetMoveType(MOVE_ERUPTION) == TYPE_FIRE); + ASSUME(GetMoveTarget(MOVE_ERUPTION) == MOVE_TARGET_BOTH); PLAYER(SPECIES_KYOGRE) {Item(ITEM_BLUE_ORB); {Speed(5);}} PLAYER(SPECIES_WOBBUFFET) {Speed(5);} OPPONENT(SPECIES_WOBBUFFET) {Speed(10);} diff --git a/test/battle/ability/protosynthesis.c b/test/battle/ability/protosynthesis.c index 2be9f81d28..5a468893e5 100644 --- a/test/battle/ability/protosynthesis.c +++ b/test/battle/ability/protosynthesis.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL); } SINGLE_BATTLE_TEST("Protosynthesis boosts the highest stat") diff --git a/test/battle/ability/psychic_surge.c b/test/battle/ability/psychic_surge.c new file mode 100644 index 0000000000..d840e8d440 --- /dev/null +++ b/test/battle/ability/psychic_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Psychic Surge creates Psychic Terrain when entering the battle"); diff --git a/test/battle/ability/purifying_salt.c b/test/battle/ability/purifying_salt.c index 495ce01a46..cb8fc6ca56 100644 --- a/test/battle/ability/purifying_salt.c +++ b/test/battle/ability/purifying_salt.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Purifying Salt halves damage from Ghost-type moves", s16 dam PARAMETRIZE { ability = ABILITY_STURDY; } PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; } GIVEN { - ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GARGANACL) { Ability(ability); } } WHEN { @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Purifying Salt halves damage from dynamic Ghost-type moves", PARAMETRIZE { ability = ABILITY_STURDY; } PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST); + ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST); PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_GHOST); } OPPONENT(SPECIES_GARGANACL) { Ability(ability); } } WHEN { @@ -61,10 +61,10 @@ SINGLE_BATTLE_TEST("Purifying Salt grants immunity to status effects") PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; } PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; } GIVEN { - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP); - ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE); - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP); + ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PURIFYING_SALT); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/quark_drive.c b/test/battle/ability/quark_drive.c index 928ee45eb5..edefdc1305 100644 --- a/test/battle/ability/quark_drive.c +++ b/test/battle/ability/quark_drive.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL); } SINGLE_BATTLE_TEST("Quark Drive boosts the highest stat") diff --git a/test/battle/ability/rain_dish.c b/test/battle/ability/rain_dish.c index 93f642c633..dc7de954c3 100644 --- a/test/battle/ability/rain_dish.c +++ b/test/battle/ability/rain_dish.c @@ -2,7 +2,7 @@ #include "test/battle.h" ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RAIN_DANCE].effect == EFFECT_RAIN_DANCE); + ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE); } SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain") diff --git a/test/battle/ability/rattled.c b/test/battle/ability/rattled.c index da8157d28a..465a688951 100644 --- a/test/battle/ability/rattled.c +++ b/test/battle/ability/rattled.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FURY_CUTTER].type == TYPE_BUG); - ASSUME(!IS_MOVE_STATUS(MOVE_FURY_CUTTER)); - ASSUME(gMovesInfo[MOVE_FEINT_ATTACK].type == TYPE_DARK); - ASSUME(!IS_MOVE_STATUS(MOVE_FEINT_ATTACK)); - ASSUME(gMovesInfo[MOVE_SHADOW_PUNCH].type == TYPE_GHOST); - ASSUME(!IS_MOVE_STATUS(MOVE_SHADOW_PUNCH)); - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(GetMoveType(MOVE_FURY_CUTTER) == TYPE_BUG); + ASSUME(!IsBattleMoveStatus(MOVE_FURY_CUTTER)); + ASSUME(GetMoveType(MOVE_FEINT_ATTACK) == TYPE_DARK); + ASSUME(!IsBattleMoveStatus(MOVE_FEINT_ATTACK)); + ASSUME(GetMoveType(MOVE_SHADOW_PUNCH) == TYPE_GHOST); + ASSUME(!IsBattleMoveStatus(MOVE_SHADOW_PUNCH)); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); } SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when hit by Bug, Dark or Ghost type move") @@ -73,8 +73,8 @@ SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when affected by Intimidate") SINGLE_BATTLE_TEST("Rattled triggers correctly when hit by U-Turn") // Specific test here, because of #3124 { GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_U_TURN].type == TYPE_BUG); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveType(MOVE_U_TURN) == TYPE_BUG); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_SUDOWOODO) {Ability(ABILITY_RATTLED); } diff --git a/test/battle/ability/refrigerate.c b/test/battle/ability/refrigerate.c index dbbaa30eb8..b3f7b59a9e 100644 --- a/test/battle/ability/refrigerate.c +++ b/test/battle/ability/refrigerate.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); } SINGLE_BATTLE_TEST("Refrigerate turns a Normal-type move into a Ice-type move") diff --git a/test/battle/ability/regenerator.c b/test/battle/ability/regenerator.c new file mode 100644 index 0000000000..0f1b432772 --- /dev/null +++ b/test/battle/ability/regenerator.c @@ -0,0 +1,50 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Regenerator heals 1/3 of max HP upon switching out") +{ + u32 currHP; + PARAMETRIZE { currHP = 1; } + PARAMETRIZE { currHP = 2; } + PARAMETRIZE { currHP = 3; } + GIVEN { + PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_REGENERATOR); HP(currHP); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + } SCENE { + SWITCH_OUT_MESSAGE("Slowbro"); + SEND_IN_MESSAGE("Wobbuffet"); + SWITCH_OUT_MESSAGE("Wobbuffet"); + SEND_IN_MESSAGE("Slowbro"); + } THEN { + EXPECT_EQ(player->hp, player->maxHP / 3 + currHP); + } +} + +SINGLE_BATTLE_TEST("Regenerator heals 1/3 of max HP upon switching out but doesn't surpass max HP") +{ + u32 currHP; + PARAMETRIZE { currHP = 5; } + PARAMETRIZE { currHP = 4; } + PARAMETRIZE { currHP = 3; } + PARAMETRIZE { currHP = 2; } + PARAMETRIZE { currHP = 1; } + GIVEN { + PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_REGENERATOR); HP(currHP); MaxHP(5); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + } SCENE { + SWITCH_OUT_MESSAGE("Slowbro"); + SEND_IN_MESSAGE("Wobbuffet"); + SWITCH_OUT_MESSAGE("Wobbuffet"); + SEND_IN_MESSAGE("Slowbro"); + } THEN { + EXPECT_LE(player->hp, player->maxHP); + } +} diff --git a/test/battle/ability/rocky_payload.c b/test/battle/ability/rocky_payload.c index 27cc45fda0..6756b98b8b 100644 --- a/test/battle/ability/rocky_payload.c +++ b/test/battle/ability/rocky_payload.c @@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Rocky Payload increases Rock-type move damage", s16 damage) PARAMETRIZE { move = MOVE_POWER_GEM; ability = ABILITY_ROCKY_PAYLOAD; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ROCK); - ASSUME(gMovesInfo[MOVE_ROCK_THROW].type == TYPE_ROCK); - ASSUME(gMovesInfo[MOVE_POWER_GEM].type == TYPE_ROCK); - ASSUME(gMovesInfo[MOVE_ROCK_THROW].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_POWER_GEM].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ROCK); + ASSUME(GetMoveType(MOVE_ROCK_THROW) == TYPE_ROCK); + ASSUME(GetMoveType(MOVE_POWER_GEM) == TYPE_ROCK); + ASSUME(GetMoveCategory(MOVE_ROCK_THROW) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_POWER_GEM) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_BOMBIRDIER) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/sand_veil.c b/test/battle/ability/sand_veil.c index f42c267273..7622d18763 100644 --- a/test/battle/ability/sand_veil.c +++ b/test/battle/ability/sand_veil.c @@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Sand Veil increases evasion during sandstorm") { PASSES_RANDOMLY(4, 5, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_POUND].accuracy == 100); + ASSUME(GetMoveAccuracy(MOVE_POUND) == 100); PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/sap_sipper.c b/test/battle/ability/sap_sipper.c index d691d4e91a..aeb746d2c6 100644 --- a/test/battle/ability/sap_sipper.c +++ b/test/battle/ability/sap_sipper.c @@ -61,7 +61,7 @@ SINGLE_BATTLE_TEST("Sap Sipper does not increase Attack if already maxed") SINGLE_BATTLE_TEST("Sap Sipper blocks multi-hit grass type moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT); PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); } OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } } WHEN { diff --git a/test/battle/ability/seed_sower.c b/test/battle/ability/seed_sower.c index 5134bc1311..ad4beea515 100644 --- a/test/battle/ability/seed_sower.c +++ b/test/battle/ability/seed_sower.c @@ -49,8 +49,8 @@ DOUBLE_BATTLE_TEST("Multi-target moves hit correct battlers after Seed Sower is } GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_PLAYER_LEFT]); } PLAYER(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_PLAYER_RIGHT]); } OPPONENT(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_OPPONENT_LEFT]); } diff --git a/test/battle/ability/sharpness.c b/test/battle/ability/sharpness.c index 8ecb07671d..38ed79f86f 100644 --- a/test/battle/ability/sharpness.c +++ b/test/battle/ability/sharpness.c @@ -11,8 +11,8 @@ SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves", s16 damage) PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_STEADFAST; } GIVEN { - ASSUME(gMovesInfo[MOVE_AERIAL_ACE].slicingMove); - ASSUME(!gMovesInfo[MOVE_SCRATCH].slicingMove); + ASSUME(IsSlicingMove(MOVE_AERIAL_ACE)); + ASSUME(!IsSlicingMove(MOVE_SCRATCH)); PLAYER(SPECIES_GALLADE) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/shed_skin.c b/test/battle/ability/shed_skin.c index e4ab6b736c..2df293ecb4 100644 --- a/test/battle/ability/shed_skin.c +++ b/test/battle/ability/shed_skin.c @@ -8,7 +8,7 @@ SINGLE_BATTLE_TEST("Shed Skin triggers 33% of the time") else PASSES_RANDOMLY(33, 100, RNG_SHED_SKIN); GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ARBOK) { Status1(STATUS1_POISON); Ability(ABILITY_SHED_SKIN); } } WHEN { diff --git a/test/battle/ability/sheer_force.c b/test/battle/ability/sheer_force.c index 97dee48a31..c5add71df0 100644 --- a/test/battle/ability/sheer_force.c +++ b/test/battle/ability/sheer_force.c @@ -7,64 +7,921 @@ ASSUMPTIONS ASSUME(MoveIsAffectedBySheerForce(MOVE_ELECTRO_SHOT) == TRUE); } -SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of moves", s16 damage) +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Magnitude", s16 damage) { - s32 j; - u32 ability = 0, move = 0; - - for (j = 1; j < MOVES_COUNT; j++) - { - if (MoveIsAffectedBySheerForce(j) - //&& gMovesInfo[j].effect != EFFECT_ORDER_UP - && gMovesInfo[j].effect != EFFECT_AURA_WHEEL - && gMovesInfo[j].effect != EFFECT_PLACEHOLDER) - { - PARAMETRIZE { ability = ABILITY_ANGER_POINT; move = j; } - PARAMETRIZE { ability = ABILITY_SHEER_FORCE; move = j; } - } - } - + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } GIVEN { - PLAYER(SPECIES_TAUROS) { Ability(ability); Status1(move == MOVE_SNORE ? STATUS1_SLEEP : STATUS1_NONE); } + PLAYER(SPECIES_TAUROS) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect - TURN { MOVE(opponent, MOVE_AGILITY); MOVE(player, move); } - else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move - TURN { MOVE(opponent, MOVE_QUICK_ATTACK); MOVE(player, move); } - else - TURN { MOVE(player, move); } - if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE) { - TURN { SKIP_TURN(player); } - TURN { ; } - } + TURN { MOVE(player, MOVE_MAGNITUDE); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, move, player); HP_BAR(opponent, captureDamage: &results[i].damage); - if (ability == ABILITY_SHEER_FORCE) { - NONE_OF { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - STATUS_ICON(opponent, STATUS1_FREEZE); - STATUS_ICON(opponent, STATUS1_POISON); - STATUS_ICON(opponent, STATUS1_BURN); - STATUS_ICON(opponent, STATUS1_TOXIC_POISON); - STATUS_ICON(opponent, STATUS1_PARALYSIS); - MESSAGE("Wobbuffet is confused!"); - MESSAGE("Wobbuffet flinched and couldn't move!"); - } - // Volt Tackle/Flare Blitz edge case: recoil happens, but target isn't statused - if (gMovesInfo[move].recoil > 0) - { - HP_BAR(player); - MESSAGE("Tauros was damaged by the recoil!"); - } - } } FINALLY { - s32 j; - for (j = 0; j < gBattleTestRunnerState->parametersCount; j+=2) - { - EXPECT_GT(results[j+1].damage, results[j].damage); - } + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Eruption", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PRESENT); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Water Spout", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PRESENT); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Present", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PRESENT); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Psywave", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PSYWAVE); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Round", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ROUND); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Gyro Ball", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_GYRO_BALL); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Electro Ball", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRO_BALL); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Dragon Energy", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DRAGON_ENERGY); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Belch", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BELCH); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Shell Trap", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SHELL_TRAP); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Burn Up", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ZEN_MODE; } + GIVEN { + PLAYER(SPECIES_DARMANITAN) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BURN_UP); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Double Shock", s16 damage) +{ + u16 move = 0; + PARAMETRIZE { move = MOVE_SKILL_SWAP; } + PARAMETRIZE { move = MOVE_CELEBRATE; } + GIVEN { + PLAYER(SPECIES_PIKACHU); + OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }; + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_DOUBLE_SHOCK); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Steel Roller", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_GRASSY_TERRAIN); MOVE(player, MOVE_STEEL_ROLLER); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Synchronoise", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_CHANSEY); + } WHEN { + TURN { MOVE(player, MOVE_SYNCHRONOISE); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Aura Wheel", s16 damage) +{ + u16 move = 0; + PARAMETRIZE { move = MOVE_SKILL_SWAP; } + PARAMETRIZE { move = MOVE_CELEBRATE; } + GIVEN { + PLAYER(SPECIES_MORPEKO); + OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }; + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_AURA_WHEEL); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Hyperspace Fury", s16 damage) +{ + u16 move = 0; + PARAMETRIZE { move = MOVE_SKILL_SWAP; } + PARAMETRIZE { move = MOVE_CELEBRATE; } + GIVEN { + PLAYER(SPECIES_HOOPA_UNBOUND); + OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); }; + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_HYPERSPACE_FURY); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Bolt Beak", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BOLT_BEAK); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Fishious Rend", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FISHIOUS_REND); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_COMEUPPANCE); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} +SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage) +{ + u16 ability = 0; + PARAMETRIZE { ability = ABILITY_SHEER_FORCE; } + PARAMETRIZE { ability = ABILITY_ANGER_POINT; } + GIVEN { + PLAYER(SPECIES_TAUROS) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PAYBACK); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + EXPECT_NE(results[0].damage, 0); + } +} + +static inline bool32 IgnoreMoveForSheerForceBoost(u32 move) +{ + switch (move) { + case MOVE_PSYWAVE: // Just skip Psywve + case MOVE_PRESENT: // And Present... + case MOVE_MAGNITUDE: // And Magnitude... + case MOVE_ERUPTION: // And Eruption... + case MOVE_WATER_SPOUT: + case MOVE_GYRO_BALL: + case MOVE_SYNCHRONOISE: + case MOVE_ELECTRO_BALL: + case MOVE_ROUND: + case MOVE_BELCH: + case MOVE_HYPERSPACE_FURY: + case MOVE_BURN_UP: + case MOVE_SHELL_TRAP: + case MOVE_BOLT_BEAK: + case MOVE_FISHIOUS_REND: + case MOVE_AURA_WHEEL: + case MOVE_STEEL_ROLLER: + case MOVE_DRAGON_ENERGY: + case MOVE_DOUBLE_SHOCK: + case MOVE_COMEUPPANCE: + case MOVE_UPPER_HAND: // Bugged? + case MOVE_GLITZY_GLOW: // Light Screen Move Effect seems to be bugged + case MOVE_PAYBACK: + return TRUE; + } + return FALSE; +} + +static inline bool32 IsMoveSheerForceBoosted(u32 move) +{ + switch (move) { + case MOVE_AIR_SLASH: + case MOVE_ANCIENT_POWER: + case MOVE_ASTONISH: + case MOVE_BITE: + case MOVE_BLIZZARD: + case MOVE_BODY_SLAM: + case MOVE_BOUNCE: + case MOVE_BREAKING_SWIPE: + case MOVE_BUBBLE: + case MOVE_BUBBLE_BEAM: + case MOVE_BUG_BUZZ: + case MOVE_BULLDOZE: + case MOVE_BURNING_JEALOUSY: + case MOVE_CHARGE_BEAM: + case MOVE_CHILLING_WATER: + case MOVE_CONFUSION: + case MOVE_CRUNCH: + case MOVE_CRUSH_CLAW: + case MOVE_DARK_PULSE: + case MOVE_DRAGON_RUSH: + case MOVE_DRAGON_BREATH: + case MOVE_DYNAMIC_PUNCH: + case MOVE_EARTH_POWER: + case MOVE_EMBER: + case MOVE_ESPER_WING: + case MOVE_EXTRASENSORY: + case MOVE_FAKE_OUT: + case MOVE_FIRE_BLAST: + case MOVE_FIRE_FANG: + case MOVE_FIRE_PUNCH: + case MOVE_FLAME_CHARGE: + case MOVE_FLAME_WHEEL: + case MOVE_FLAMETHROWER: + case MOVE_FLARE_BLITZ: + case MOVE_FLASH_CANNON: + case MOVE_FOCUS_BLAST: + case MOVE_FORCE_PALM: + case MOVE_GUNK_SHOT: + case MOVE_HEADBUTT: + case MOVE_HEAT_WAVE: + case MOVE_HURRICANE: + case MOVE_ICE_BEAM: + case MOVE_ICE_FANG: + case MOVE_ICE_PUNCH: + case MOVE_ICICLE_CRASH: + case MOVE_ICY_WIND: + case MOVE_IRON_HEAD: + case MOVE_IRON_TAIL: + case MOVE_LAVA_PLUME: + case MOVE_LIQUIDATION: + case MOVE_LOW_SWEEP: + case MOVE_METAL_CLAW: + case MOVE_MUD_BOMB: + case MOVE_MUDDY_WATER: + case MOVE_MUD_SHOT: + case MOVE_MUD_SLAP: + case MOVE_MYSTICAL_FIRE: + case MOVE_PLAY_ROUGH: + case MOVE_POISON_FANG: + case MOVE_POISON_JAB: + case MOVE_POISON_STING: + case MOVE_POISON_TAIL: + case MOVE_POUNCE: + case MOVE_POWER_UP_PUNCH: + case MOVE_PSYBEAM: + case MOVE_PSYCHIC: + case MOVE_RAZOR_SHELL: + case MOVE_ROCK_CLIMB: + case MOVE_ROCK_SLIDE: + case MOVE_ROCK_SMASH: + case MOVE_ROCK_TOMB: + case MOVE_SANDSEAR_STORM: + case MOVE_SCALD: + case MOVE_SCORCHING_SANDS: + case MOVE_SECRET_POWER: + case MOVE_SHADOW_BALL: + case MOVE_SIGNAL_BEAM: + case MOVE_SKY_ATTACK: + case MOVE_SLUDGE_BOMB: + case MOVE_SLUDGE_WAVE: + case MOVE_SNARL: + case MOVE_SNORE: + case MOVE_STEEL_WING: + case MOVE_STOMP: + case MOVE_STONE_AXE: + case MOVE_STRUGGLE_BUG: + case MOVE_THROAT_CHOP: + case MOVE_THUNDER: + case MOVE_THUNDER_FANG: + case MOVE_THUNDERBOLT: + case MOVE_THUNDER_PUNCH: + case MOVE_TRAILBLAZE: + case MOVE_TWISTER: + case MOVE_UPPER_HAND: + case MOVE_WATER_PULSE: + case MOVE_WATERFALL: + case MOVE_ZAP_CANNON: + case MOVE_ZEN_HEADBUTT: + case MOVE_ACID: + case MOVE_ACID_SPRAY: + case MOVE_ALLURING_VOICE: + case MOVE_ANCHOR_SHOT: + case MOVE_APPLE_ACID: + case MOVE_AQUA_STEP: + case MOVE_AURA_WHEEL: + case MOVE_AURORA_BEAM: + case MOVE_AXE_KICK: + case MOVE_BARB_BARRAGE: + case MOVE_BITTER_MALICE: + case MOVE_BLAZE_KICK: + case MOVE_BLAZING_TORQUE: + case MOVE_BLEAKWIND_STORM: + case MOVE_BLUE_FLARE: + case MOVE_BOLT_STRIKE: + case MOVE_BONE_CLUB: + case MOVE_CEASELESS_EDGE: + case MOVE_CHATTER: + case MOVE_CLANGOROUS_SOULBLAZE: + case MOVE_COMBAT_TORQUE: + case MOVE_CONSTRICT: + case MOVE_CROSS_POISON: + case MOVE_DIAMOND_STORM: + case MOVE_DIRE_CLAW: + case MOVE_DISCHARGE: + case MOVE_DIZZY_PUNCH: + case MOVE_DOUBLE_IRON_BASH: + case MOVE_DRUM_BEATING: + case MOVE_EERIE_SPELL: + case MOVE_ELECTROWEB: + case MOVE_ENERGY_BALL: + case MOVE_FIERY_DANCE: + case MOVE_FIERY_WRATH: + case MOVE_FREEZING_GLARE: + case MOVE_FIRE_LASH: + case MOVE_FREEZE_DRY: + case MOVE_FREEZE_SHOCK: + case MOVE_GENESIS_SUPERNOVA: + case MOVE_GLACIATE: + case MOVE_GRAV_APPLE: + case MOVE_HEART_STAMP: + case MOVE_HYPER_FANG: + case MOVE_ICE_BURN: + case MOVE_INFERNAL_PARADE: + case MOVE_INFERNO: + case MOVE_LEAF_TORNADO: + case MOVE_LICK: + case MOVE_LUMINA_CRASH: + case MOVE_LUNGE: + case MOVE_LUSTER_PURGE: + case MOVE_MAGICAL_TORQUE: + case MOVE_MALIGNANT_CHAIN: + case MOVE_MATCHA_GOTCHA: + case MOVE_METEOR_MASH: + case MOVE_MIRROR_SHOT: + case MOVE_MIST_BALL: + case MOVE_MOONBLAST: + case MOVE_MORTAL_SPIN: + case MOVE_MOUNTAIN_GALE: + case MOVE_MYSTICAL_POWER: + case MOVE_NEEDLE_ARM: + case MOVE_NIGHT_DAZE: + case MOVE_NOXIOUS_TORQUE: + case MOVE_NUZZLE: + case MOVE_OCTAZOOKA: + case MOVE_OMINOUS_WIND: + case MOVE_ORDER_UP: + case MOVE_POWDER_SNOW: + case MOVE_PSYSHIELD_BASH: + case MOVE_PYRO_BALL: + case MOVE_RAPID_SPIN: + case MOVE_RELIC_SONG: + case MOVE_ROLLING_KICK: + case MOVE_SACRED_FIRE: + case MOVE_SALT_CURE: + case MOVE_SEARING_SHOT: + case MOVE_SEED_FLARE: + case MOVE_SHADOW_BONE: + case MOVE_SHELL_SIDE_ARM: + case MOVE_SILVER_WIND: + case MOVE_SKITTER_SMACK: + case MOVE_SLUDGE: + case MOVE_SMOG: + case MOVE_SPARK: + case MOVE_SPARKLING_ARIA: + case MOVE_SPIRIT_BREAK: + case MOVE_SPIRIT_SHACKLE: + case MOVE_SPLISHY_SPLASH: + case MOVE_SPRINGTIDE_STORM: + case MOVE_STEAM_ERUPTION: + case MOVE_STEAMROLLER: + case MOVE_STOKED_SPARKSURFER: + case MOVE_STRANGE_STEAM: + case MOVE_SYRUP_BOMB: + case MOVE_THUNDER_SHOCK: + case MOVE_THUNDEROUS_KICK: + case MOVE_TORCH_SONG: + case MOVE_TRI_ATTACK: + case MOVE_TRIPLE_ARROWS: + case MOVE_TROP_KICK: + case MOVE_TWINEEDLE: + case MOVE_VOLT_TACKLE: + case MOVE_WICKED_TORQUE: + case MOVE_WILDBOLT_STORM: + case MOVE_ZING_ZAP: + case MOVE_ELECTRO_SHOT: + case MOVE_PSYCHIC_NOISE: + return TRUE; + } + return FALSE; +} + +// Test split into four parts that handles ~1/4 of all moves each +DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 1") +{ + s16 damage1, damage2; + u32 move = 0; + for (u32 j = 1; j < MOVES_COUNT; j += 4) + if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j)) + PARAMETRIZE { move = j; } + GIVEN { + PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + } WHEN { + if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect + TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND) + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); + MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft); + MOVE(playerLeft, move, target: opponentRight); + MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST) + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP) + TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_DREAM_EATER) + { + TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SNORE) + { + TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT) + { + TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + switch (GetMoveEffect(move)) + { + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_SEMI_INVULNERABLE: + case EFFECT_SOLAR_BEAM: + case EFFECT_SKY_DROP: + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { ; } + break; + case EFFECT_FUTURE_SIGHT: + TURN { ; } + TURN { ; } + break; + case EFFECT_BIDE: + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + break; + } + } SCENE { + if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT) + { + HP_BAR(opponentRight, captureDamage: &damage1); + HP_BAR(playerRight, captureDamage: &damage2); + } + else + { + HP_BAR(playerRight, captureDamage: &damage2); + HP_BAR(opponentRight, captureDamage: &damage1); + } + } THEN { + if (IsMoveSheerForceBoosted(move)) + EXPECT_GT(damage1, damage2); + else + EXPECT_EQ(damage2, damage1); + } +} +DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 2") +{ + s16 damage1, damage2; + u32 move = 0; + for (u32 j = 2; j < MOVES_COUNT; j += 4) + if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j)) + PARAMETRIZE { move = j; } + GIVEN { + PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + } WHEN { + if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect + TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND) + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); + MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft); + MOVE(playerLeft, move, target: opponentRight); + MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST) + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP) + TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_DREAM_EATER) + { + TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SNORE) + { + TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT) + { + TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + switch (GetMoveEffect(move)) + { + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_SEMI_INVULNERABLE: + case EFFECT_SOLAR_BEAM: + case EFFECT_SKY_DROP: + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { ; } + break; + case EFFECT_FUTURE_SIGHT: + TURN { ; } + TURN { ; } + break; + case EFFECT_BIDE: + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + break; + } + } SCENE { + if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT) + { + HP_BAR(opponentRight, captureDamage: &damage1); + HP_BAR(playerRight, captureDamage: &damage2); + } + else + { + HP_BAR(playerRight, captureDamage: &damage2); + HP_BAR(opponentRight, captureDamage: &damage1); + } + } THEN { + if (IsMoveSheerForceBoosted(move)) + EXPECT_GT(damage1, damage2); + else + EXPECT_EQ(damage2, damage1); + } +} +DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 3") +{ + s16 damage1, damage2; + u32 move = 0; + for (u32 j = 3; j < MOVES_COUNT; j += 4) + if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j)) + PARAMETRIZE { move = j; } + GIVEN { + PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + } WHEN { + if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect + TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND) + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); + MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft); + MOVE(playerLeft, move, target: opponentRight); + MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST) + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP) + TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_DREAM_EATER) + { + TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SNORE) + { + TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT) + { + TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + switch (GetMoveEffect(move)) + { + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_SEMI_INVULNERABLE: + case EFFECT_SOLAR_BEAM: + case EFFECT_SKY_DROP: + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { ; } + break; + case EFFECT_FUTURE_SIGHT: + TURN { ; } + TURN { ; } + break; + case EFFECT_BIDE: + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + break; + } + } SCENE { + if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT) + { + HP_BAR(opponentRight, captureDamage: &damage1); + HP_BAR(playerRight, captureDamage: &damage2); + } + else + { + HP_BAR(playerRight, captureDamage: &damage2); + HP_BAR(opponentRight, captureDamage: &damage1); + } + } THEN { + if (IsMoveSheerForceBoosted(move)) + EXPECT_GT(damage1, damage2); + else + EXPECT_EQ(damage2, damage1); + } +} +DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 4") +{ + s16 damage1, damage2; + u32 move = 0; + for (u32 j = 4; j < MOVES_COUNT; j += 4) + { + if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j)) + PARAMETRIZE { move = j; } + } + GIVEN { + PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); } + } WHEN { + if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect + TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND) + TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); + MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft); + MOVE(playerLeft, move, target: opponentRight); + MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST) + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP) + TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + else if (move == MOVE_DREAM_EATER) + { + TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SNORE) + { + TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT) + { + TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); } + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + } + else + TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); } + switch (GetMoveEffect(move)) + { + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_SEMI_INVULNERABLE: + case EFFECT_SOLAR_BEAM: + case EFFECT_SKY_DROP: + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { ; } + break; + case EFFECT_FUTURE_SIGHT: + TURN { ; } + TURN { ; } + break; + case EFFECT_BIDE: + TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); } + break; + } + } SCENE { + if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT) + { + HP_BAR(opponentRight, captureDamage: &damage1); + HP_BAR(playerRight, captureDamage: &damage2); + } + else + { + HP_BAR(playerRight, captureDamage: &damage2); + HP_BAR(opponentRight, captureDamage: &damage1); + } + } THEN { + if (IsMoveSheerForceBoosted(move)) + EXPECT_GT(damage1, damage2); + else + EXPECT_EQ(damage2, damage1); } } diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c index 9374a5f018..5833615027 100644 --- a/test/battle/ability/shield_dust.c +++ b/test/battle/ability/shield_dust.c @@ -124,7 +124,6 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o DOUBLE_BATTLE_TEST("Shield Dust does or does not block Sparkling Aria depending on number of targets hit") { u32 moveToUse; - KNOWN_FAILING; PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; } PARAMETRIZE { moveToUse = MOVE_TACKLE; } GIVEN { @@ -148,9 +147,23 @@ DOUBLE_BATTLE_TEST("Shield Dust does or does not block Sparkling Aria depending } } +DOUBLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria if all other targets avoid getting hit by") +{ + KNOWN_FAILING; // #4636 + GIVEN { + PLAYER(SPECIES_PRIMARINA); + PLAYER(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); } + OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } + OPPONENT(SPECIES_WYNAUT) { Status1(STATUS1_BURN); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_FLY, target:playerLeft); MOVE(opponentRight, MOVE_PROTECT); MOVE(playerRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_SPARKLING_ARIA); } + } SCENE { + NOT MESSAGE("Vivillon's burn was cured!"); + } +} + SINGLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria in singles") { - KNOWN_FAILING; GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); } diff --git a/test/battle/ability/snow_cloak.c b/test/battle/ability/snow_cloak.c index a4d1acadb7..4e129c3ff7 100644 --- a/test/battle/ability/snow_cloak.c +++ b/test/battle/ability/snow_cloak.c @@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Snow Cloak increases evasion during hail") { PASSES_RANDOMLY(4, 5, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_POUND].accuracy == 100); + ASSUME(GetMoveAccuracy(MOVE_POUND) == 100); PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/stalwart.c b/test/battle/ability/stalwart.c index 6f8acd6d82..22debe74cd 100644 --- a/test/battle/ability/stalwart.c +++ b/test/battle/ability/stalwart.c @@ -24,8 +24,8 @@ DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirectin PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; } PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; } GIVEN { - ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STALWART); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } diff --git a/test/battle/ability/stamina.c b/test/battle/ability/stamina.c index 5bf7dc09a6..172154cc85 100644 --- a/test/battle/ability/stamina.c +++ b/test/battle/ability/stamina.c @@ -24,10 +24,10 @@ SINGLE_BATTLE_TEST("Stamina raises Defense by 1 when hit by a move") PARAMETRIZE {move = MOVE_GUST; } GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); - ASSUME(!IS_MOVE_STATUS(MOVE_GUST)); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_GUST)); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STAMINA); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,7 +56,7 @@ DOUBLE_BATTLE_TEST("Stamina activates correctly for every battler with the abili PARAMETRIZE {abilityLeft = ABILITY_STAMINA, abilityRight = ABILITY_STAMINA; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET) { Ability(abilityLeft); Speed(10); } PLAYER(SPECIES_WOBBUFFET) { Ability(abilityRight); Speed(5); } OPPONENT(SPECIES_WOBBUFFET) {Speed(20); } diff --git a/test/battle/ability/stance_change.c b/test/battle/ability/stance_change.c index 8221e16385..d6e08909f9 100644 --- a/test/battle/ability/stance_change.c +++ b/test/battle/ability/stance_change.c @@ -63,9 +63,8 @@ SINGLE_BATTLE_TEST("Stance Change changes Aegislash from Blade to Shield when us SINGLE_BATTLE_TEST("Stance Change doesn't change Aegislash to Shield if King's Shield is called by a different move - Sleep Talk") { - KNOWN_FAILING; // Currently does change form GIVEN { - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); PLAYER(SPECIES_AEGISLASH_BLADE) { Moves(MOVE_KINGS_SHIELD, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/static.c b/test/battle/ability/static.c index 3c5d042cd0..8d5a27c6b5 100644 --- a/test/battle/ability/static.c +++ b/test/battle/ability/static.c @@ -7,14 +7,14 @@ SINGLE_BATTLE_TEST("Static inflicts paralysis on contact") PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_SWIFT)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); } } WHEN { TURN { MOVE(player, move); } } SCENE { - if (gMovesInfo[move].makesContact) { + if (MoveMakesContact(move)) { ABILITY_POPUP(opponent, ABILITY_STATIC); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player); MESSAGE("The opposing Pikachu's Static paralyzed Wobbuffet, so it may be unable to move!"); @@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Static triggers 30% of the time") PASSES_RANDOMLY(3, 10, RNG_STATIC); GIVEN { ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); } } WHEN { diff --git a/test/battle/ability/steelworker.c b/test/battle/ability/steelworker.c index 7e8ecbb568..23d4be2917 100644 --- a/test/battle/ability/steelworker.c +++ b/test/battle/ability/steelworker.c @@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Steelworker increases Steel-type move damage", s16 damage) PARAMETRIZE { move = MOVE_FLASH_CANNON; ability = ABILITY_STEELWORKER; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_STEEL); - ASSUME(gMovesInfo[MOVE_ANCHOR_SHOT].type == TYPE_STEEL); - ASSUME(gMovesInfo[MOVE_FLASH_CANNON].type == TYPE_STEEL); - ASSUME(gMovesInfo[MOVE_ANCHOR_SHOT].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_FLASH_CANNON].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_STEEL); + ASSUME(GetMoveType(MOVE_ANCHOR_SHOT) == TYPE_STEEL); + ASSUME(GetMoveType(MOVE_FLASH_CANNON) == TYPE_STEEL); + ASSUME(GetMoveCategory(MOVE_ANCHOR_SHOT) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_FLASH_CANNON) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_DHELMISE) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/stench.c b/test/battle/ability/stench.c index 76b36f3ff3..f1484de6c9 100644 --- a/test/battle/ability/stench.c +++ b/test/battle/ability/stench.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Stench has a 10% chance to flinch") { PASSES_RANDOMLY(1, 10, RNG_STENCH); GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); PLAYER(SPECIES_GRIMER) { Ability(ABILITY_STENCH); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Stench does not stack with King's Rock") PASSES_RANDOMLY(1, 10, RNG_STENCH); GIVEN { ASSUME(gItemsInfo[ITEM_KINGS_ROCK].holdEffect == HOLD_EFFECT_FLINCH); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); PLAYER(SPECIES_GRIMER) { Ability(ABILITY_STENCH); Item(ITEM_KINGS_ROCK); } OPPONENT(SPECIES_WOBBUFFET); @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Stench does not stack with King's Rock") DOUBLE_BATTLE_TEST("Stench only triggers if target takes damage") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100)); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); @@ -58,7 +58,7 @@ DOUBLE_BATTLE_TEST("Stench only triggers if target takes damage") DOUBLE_BATTLE_TEST("Stench doesn't trigger if partner uses a move") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100)); PLAYER(SPECIES_WOBBUFFET) { Speed(20); } PLAYER(SPECIES_WYNAUT) { Speed(10); } diff --git a/test/battle/ability/storm_drain.c b/test/battle/ability/storm_drain.c index b4d5a2c169..962317b108 100644 --- a/test/battle/ability/storm_drain.c +++ b/test/battle/ability/storm_drain.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. Attack [Gen5+]") { GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); } } WHEN { @@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. A DOUBLE_BATTLE_TEST("Storm Drain forces single-target Water-type moves to target the Pokémon with this Ability.") { GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); } diff --git a/test/battle/ability/sturdy.c b/test/battle/ability/sturdy.c index b79fd5e921..5ba7e16ea8 100644 --- a/test/battle/ability/sturdy.c +++ b/test/battle/ability/sturdy.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Sturdy prevents OHKO moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO); + ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO); PLAYER(SPECIES_GEODUDE) { Ability(ABILITY_STURDY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/supreme_overlord.c b/test/battle/ability/supreme_overlord.c index f8868b4afb..eec81e89ed 100644 --- a/test/battle/ability/supreme_overlord.c +++ b/test/battle/ability/supreme_overlord.c @@ -95,7 +95,7 @@ SINGLE_BATTLE_TEST("Supreme Overlord does not boost attack if party members are SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { HP(1);} PLAYER(SPECIES_KINGAMBIT) { Ability(ABILITY_SUPREME_OVERLORD); } OPPONENT(SPECIES_WOBBUFFET); @@ -116,7 +116,7 @@ SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all batt SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1);} diff --git a/test/battle/ability/swarm.c b/test/battle/ability/swarm.c index c3da16f6b6..a70c1ffb55 100644 --- a/test/battle/ability/swarm.c +++ b/test/battle/ability/swarm.c @@ -7,9 +7,9 @@ SINGLE_BATTLE_TEST("Swarm boosts Bug-type moves in a pinch", s16 damage) PARAMETRIZE { hp = 99; } PARAMETRIZE { hp = 33; } GIVEN { - ASSUME(gMovesInfo[MOVE_BUG_BITE].type == TYPE_BUG); - ASSUME(gMovesInfo[MOVE_BUG_BITE].power == 60); - ASSUME(gMovesInfo[MOVE_BUG_BITE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveType(MOVE_BUG_BITE) == TYPE_BUG); + ASSUME(GetMovePower(MOVE_BUG_BITE) == 60); + ASSUME(GetMoveCategory(MOVE_BUG_BITE) == DAMAGE_CATEGORY_PHYSICAL); ASSUME(gSpeciesInfo[SPECIES_LEDYBA].types[0] == TYPE_BUG); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC); diff --git a/test/battle/ability/sword_of_ruin.c b/test/battle/ability/sword_of_ruin.c index 3498522423..9501322ab7 100644 --- a/test/battle/ability/sword_of_ruin.c +++ b/test/battle/ability/sword_of_ruin.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY); } SINGLE_BATTLE_TEST("Sword of Ruin reduces Defense if opposing mon's ability doesn't match") @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Sword of Ruin reduces Defense if opposing mon's ability does SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { HP(1);} PLAYER(SPECIES_CHIEN_PAO); OPPONENT(SPECIES_WOBBUFFET); @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battler SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1);} diff --git a/test/battle/ability/tablets_of_ruin.c b/test/battle/ability/tablets_of_ruin.c index c98384b805..976f929bbe 100644 --- a/test/battle/ability/tablets_of_ruin.c +++ b/test/battle/ability/tablets_of_ruin.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT); } SINGLE_BATTLE_TEST("Tablets of Ruin reduces Attack if opposing mon's ability doesn't match") @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Tablets of Ruin reduces Attack if opposing mon's ability doe SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { HP(1);} PLAYER(SPECIES_WO_CHIEN); OPPONENT(SPECIES_WOBBUFFET); @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battl SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1);} diff --git a/test/battle/ability/tangling_hair.c b/test/battle/ability/tangling_hair.c index f663465163..45f6282fb8 100644 --- a/test/battle/ability/tangling_hair.c +++ b/test/battle/ability/tangling_hair.c @@ -3,9 +3,9 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].effect == EFFECT_HIT); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE); + ASSUME(GetMoveEffect(MOVE_TACKLE) == EFFECT_HIT); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); + ASSUME(MoveMakesContact(MOVE_TACKLE) == TRUE); } @@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Tangling Hair drops opposing mon's speed if ability user got PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].makesContact == FALSE); + ASSUME(MoveMakesContact(MOVE_SWIFT) == FALSE); PLAYER(SPECIES_DUGTRIO) { Ability(ABILITY_TANGLING_HAIR); } OPPONENT(SPECIES_WYNAUT); } WHEN { diff --git a/test/battle/ability/teraform_zero.c b/test/battle/ability/teraform_zero.c index 819d0eef3d..09ce921931 100644 --- a/test/battle/ability/teraform_zero.c +++ b/test/battle/ability/teraform_zero.c @@ -39,8 +39,8 @@ DOUBLE_BATTLE_TEST("Teraform Zero can be supressed") SINGLE_BATTLE_TEST("Teraform Zero can be replaced") { GIVEN { - ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_TERAPAGOS); OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_PRANKSTER); } } WHEN { @@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Teraform Zero can be replaced") SINGLE_BATTLE_TEST("Teraform Zero cannot be swapped") { GIVEN { - ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); PLAYER(SPECIES_TERAPAGOS); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -71,7 +71,7 @@ SINGLE_BATTLE_TEST("Teraform Zero cannot be swapped") SINGLE_BATTLE_TEST("Teraform Zero cannot be copied") { GIVEN { - ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY); + ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY); PLAYER(SPECIES_TERAPAGOS); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/torrent.c b/test/battle/ability/torrent.c index df27d8e996..f0da964b93 100644 --- a/test/battle/ability/torrent.c +++ b/test/battle/ability/torrent.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Torrent boosts Water-type moves in a pinch", s16 damage) PARAMETRIZE { hp = 99; } PARAMETRIZE { hp = 33; } GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); MaxHP(99); HP(hp); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/toxic_chain.c b/test/battle/ability/toxic_chain.c index c233f5fc92..97c3fdf4f9 100644 --- a/test/battle/ability/toxic_chain.c +++ b/test/battle/ability/toxic_chain.c @@ -5,8 +5,8 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison when attacking") { PASSES_RANDOMLY(3, 10, RNG_TOXIC_CHAIN); GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveCategory(MOVE_TACKLE) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -24,9 +24,9 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison when attacking") SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison on any hit of a multi-hit move") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT); - ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].power > 0); + ASSUME(GetMoveCategory(MOVE_DOUBLE_SLAP) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT); + ASSUME(GetMovePower(MOVE_DOUBLE_SLAP) > 0); ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN); PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_PECHA_BERRY); } @@ -51,9 +51,9 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison on any hit of a multi-hit mo DOUBLE_BATTLE_TEST("Toxic Chain can inflict bad poison on both foes") { GIVEN { - ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].power > 0); + ASSUME(GetMoveCategory(MOVE_RAZOR_LEAF) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveTarget(MOVE_RAZOR_LEAF) == MOVE_TARGET_BOTH); + ASSUME(GetMovePower(MOVE_RAZOR_LEAF) > 0); PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -85,9 +85,9 @@ SINGLE_BATTLE_TEST("Toxic Chain makes Lum/Pecha Berry trigger before being knock PARAMETRIZE { item = ITEM_LUM_BERRY; } GIVEN { - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].category != DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF); - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].power > 0); + ASSUME(GetMoveCategory(MOVE_KNOCK_OFF) != DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF); + ASSUME(GetMovePower(MOVE_KNOCK_OFF) > 0); ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN); ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); } diff --git a/test/battle/ability/toxic_debris.c b/test/battle/ability/toxic_debris.c index c4a50a5d13..b3b9dbbb2e 100644 --- a/test/battle/ability/toxic_debris.c +++ b/test/battle/ability/toxic_debris.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); } SINGLE_BATTLE_TEST("Toxic Debris sets Toxic Spikes on the opposing side if hit by a physical attack") diff --git a/test/battle/ability/transistor.c b/test/battle/ability/transistor.c index 8dd1a1bdb3..eb3c015af7 100644 --- a/test/battle/ability/transistor.c +++ b/test/battle/ability/transistor.c @@ -17,11 +17,11 @@ SINGLE_BATTLE_TEST("Transistor increases Electric-type attack / special attack", PARAMETRIZE { move = MOVE_THUNDER_SHOCK; ability = ABILITY_TRANSISTOR; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_WILD_CHARGE].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_WILD_CHARGE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_WILD_CHARGE) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetMoveCategory(MOVE_WILD_CHARGE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_THUNDER_SHOCK) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_REGIELEKI) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Transistor is blocked by neutralizing gas", s16 damage) PARAMETRIZE { ability = ABILITY_LEVITATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_TRANSISTOR); } OPPONENT(SPECIES_KOFFING) { Ability(ability); } } WHEN { diff --git a/test/battle/ability/vessel_of_ruin.c b/test/battle/ability/vessel_of_ruin.c index 6531cbbf3a..4d159c0b0e 100644 --- a/test/battle/ability/vessel_of_ruin.c +++ b/test/battle/ability/vessel_of_ruin.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT); } SINGLE_BATTLE_TEST("Vessel of Ruin reduces Sp. Atk if opposing mon's ability doesn't match") @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Vessel of Ruin reduces Sp. Atk if opposing mon's ability doe SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) { HP(1);} PLAYER(SPECIES_TING_LU); OPPONENT(SPECIES_WOBBUFFET); @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battle SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1);} diff --git a/test/battle/ability/volt_absorb.c b/test/battle/ability/volt_absorb.c index 93498bd1c7..5d88cb95e4 100644 --- a/test/battle/ability/volt_absorb.c +++ b/test/battle/ability/volt_absorb.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Volt Absorb heals 25% when hit by electric type moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Volt Absorb heals 25% when hit by electric type moves") SINGLE_BATTLE_TEST("Volt Absorb does not activate if protected") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Volt Absorb does not activate if protected") SINGLE_BATTLE_TEST("Volt Absorb activates on status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveType(MOVE_THUNDER_WAVE) == TYPE_ELECTRIC); + ASSUME(GetMoveCategory(MOVE_THUNDER_WAVE) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -48,8 +48,8 @@ SINGLE_BATTLE_TEST("Volt Absorb activates on status moves") SINGLE_BATTLE_TEST("Volt Absorb is only triggered once on multi strike moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_FURY_SWIPES].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_FURY_SWIPES].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveType(MOVE_FURY_SWIPES) == TYPE_NORMAL); + ASSUME(GetMoveEffect(MOVE_FURY_SWIPES) == EFFECT_MULTI_HIT); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_GRAVELER_ALOLA) { Ability(ABILITY_GALVANIZE); } } WHEN { @@ -65,8 +65,8 @@ DOUBLE_BATTLE_TEST("Volt Absorb does not stop Electric Typed Explosion from dama { s16 damage1, damage2; GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); - ASSUME(gMovesInfo[MOVE_EXPLOSION].type == TYPE_NORMAL); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); + ASSUME(GetMoveType(MOVE_EXPLOSION) == TYPE_NORMAL); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); } PLAYER(SPECIES_ABRA); OPPONENT(SPECIES_GRAVELER_ALOLA) { Ability(ABILITY_GALVANIZE); } @@ -88,7 +88,7 @@ DOUBLE_BATTLE_TEST("Volt Absorb does not stop Electric Typed Explosion from dama SINGLE_BATTLE_TEST("Volt Absorb prevents Cell Battery from activating") { GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); Item(ITEM_CELL_BATTERY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/water_absorb.c b/test/battle/ability/water_absorb.c index 842a448bab..1c0406ebdc 100644 --- a/test/battle/ability/water_absorb.c +++ b/test/battle/ability/water_absorb.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Water Absorb heals 25% when hit by water type moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Water Absorb heals 25% when hit by water type moves") SINGLE_BATTLE_TEST("Water Absorb does not activate if protected") { GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Water Absorb does not activate if protected") SINGLE_BATTLE_TEST("Water Absorb activates on status moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_SOAK].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_SOAK].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveType(MOVE_SOAK) == TYPE_WATER); + ASSUME(GetMoveCategory(MOVE_SOAK) == DAMAGE_CATEGORY_STATUS); PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -48,8 +48,8 @@ SINGLE_BATTLE_TEST("Water Absorb activates on status moves") SINGLE_BATTLE_TEST("Water Absorb is only triggered once on multi strike moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveType(MOVE_WATER_SHURIKEN) == TYPE_WATER); + ASSUME(GetMoveEffect(MOVE_WATER_SHURIKEN) == EFFECT_MULTI_HIT); PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Water Absorb prevents Absorb Bulb and Luminous Moss from act PARAMETRIZE { item = ITEM_ABSORB_BULB; } PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; } GIVEN { - ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER); PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/weak_armor.c b/test/battle/ability/weak_armor.c index 0d264e7ff9..12e9ef3bcc 100644 --- a/test/battle/ability/weak_armor.c +++ b/test/battle/ability/weak_armor.c @@ -3,10 +3,10 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); - ASSUME(!IS_MOVE_STATUS(MOVE_GUST)); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_GUST)); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); ASSUME(B_WEAK_ARMOR_SPEED >= GEN_7); } @@ -50,8 +50,8 @@ SINGLE_BATTLE_TEST("Weak Armor lowers Defense by 1 and boosts Speed by 2 when hi SINGLE_BATTLE_TEST("Weak Armor does not trigger when brought in by Dragon Tail and taking Stealth Rock damage") { GIVEN { - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/wind_power.c b/test/battle/ability/wind_power.c index 9ad42fad0f..fd4a4b95f5 100644 --- a/test/battle/ability/wind_power.c +++ b/test/battle/ability/wind_power.c @@ -3,16 +3,16 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_THUNDERBOLT)); - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); - ASSUME(!IS_MOVE_STATUS(MOVE_AIR_CUTTER)); - ASSUME(gMovesInfo[MOVE_AIR_CUTTER].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_AIR_CUTTER].windMove == TRUE); - ASSUME(!IS_MOVE_STATUS(MOVE_PETAL_BLIZZARD)); - ASSUME(gMovesInfo[MOVE_PETAL_BLIZZARD].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_PETAL_BLIZZARD].windMove == TRUE); - ASSUME(gMovesInfo[MOVE_TACKLE].windMove == FALSE); + ASSUME(!IsBattleMoveStatus(MOVE_THUNDERBOLT)); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_AIR_CUTTER)); + ASSUME(GetMoveTarget(MOVE_AIR_CUTTER) == MOVE_TARGET_BOTH); + ASSUME(IsWindMove(MOVE_AIR_CUTTER)); + ASSUME(!IsBattleMoveStatus(MOVE_PETAL_BLIZZARD)); + ASSUME(GetMoveTarget(MOVE_PETAL_BLIZZARD) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(IsWindMove(MOVE_PETAL_BLIZZARD)); + ASSUME(!IsWindMove(MOVE_TACKLE)); } SINGLE_BATTLE_TEST("Wind Power sets up Charge for player when hit by a wind move") @@ -193,7 +193,7 @@ DOUBLE_BATTLE_TEST("Wind Power activates correctly when Tailwind is used") PARAMETRIZE {opponentSide = FALSE;} GIVEN { - ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); + ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(10); } PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(5); } OPPONENT(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(20); } diff --git a/test/battle/ability/wind_rider.c b/test/battle/ability/wind_rider.c index 44baacc8a2..d68414d060 100644 --- a/test/battle/ability/wind_rider.c +++ b/test/battle/ability/wind_rider.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); - ASSUME(gMovesInfo[MOVE_TAILWIND].windMove == TRUE); + ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); + ASSUME(IsWindMove(MOVE_TAILWIND)); } SINGLE_BATTLE_TEST("Wind Rider raises Attack by one stage if it sets up Tailwind") @@ -108,7 +108,7 @@ SINGLE_BATTLE_TEST("Wind Rider activates when it's no longer effected by Neutral SINGLE_BATTLE_TEST("Wind Rider absorbs Wind moves and raises Attack by one stage") { GIVEN { - ASSUME(gMovesInfo[MOVE_GUST].windMove == TRUE); + ASSUME(IsWindMove(MOVE_GUST)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } } WHEN { diff --git a/test/battle/ability/zero_to_hero.c b/test/battle/ability/zero_to_hero.c index 733104f153..195bb44289 100644 --- a/test/battle/ability/zero_to_hero.c +++ b/test/battle/ability/zero_to_hero.c @@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Zero to Hero transforms both player and opponent") SINGLE_BATTLE_TEST("Zero to Hero will activate if a switch move is used") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLIP_TURN].effect == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_FLIP_TURN) == EFFECT_HIT_ESCAPE); PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -83,9 +83,9 @@ SINGLE_BATTLE_TEST("Gastro Acid, Worry Seed, and Simple Beam fail if the target PARAMETRIZE { move = MOVE_SIMPLE_BEAM; } GIVEN { - ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID); - ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED); - ASSUME(gMovesInfo[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM); + ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID); + ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED); + ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM); PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -139,7 +139,7 @@ SINGLE_BATTLE_TEST("Imposter doesn't apply the heroic transformation message whe SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers fainted - Player") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_PALAFIN_ZERO); PLAYER(SPECIES_WOBBUFFET) { HP(1);} OPPONENT(SPECIES_WOBBUFFET); @@ -162,7 +162,7 @@ SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers fainted - Opponent") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PALAFIN_ZERO); diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c index 0883e3cc59..e9b5a2e51c 100644 --- a/test/battle/ai/ai.c +++ b/test/battle/ai/ai.c @@ -80,25 +80,25 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves with better accuracy, but only if they b AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(hp); } PLAYER(SPECIES_WOBBUFFET); - ASSUME(gMovesInfo[MOVE_SWIFT].accuracy == 0); - ASSUME(gMovesInfo[MOVE_SLAM].power == gMovesInfo[MOVE_STRENGTH].power); - ASSUME(gMovesInfo[MOVE_MEGA_KICK].power > gMovesInfo[MOVE_STRENGTH].power); - ASSUME(gMovesInfo[MOVE_SLAM].accuracy < gMovesInfo[MOVE_STRENGTH].accuracy); - ASSUME(gMovesInfo[MOVE_MEGA_KICK].accuracy < gMovesInfo[MOVE_STRENGTH].accuracy); - ASSUME(gMovesInfo[MOVE_TACKLE].accuracy == 100); - ASSUME(gMovesInfo[MOVE_GUST].accuracy == 100); - ASSUME(gMovesInfo[MOVE_SHOCK_WAVE].accuracy == 0); - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].accuracy == 100); - ASSUME(gMovesInfo[MOVE_ICY_WIND].accuracy != 100); - ASSUME(gMovesInfo[MOVE_SLAM].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_MEGA_KICK].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_SHOCK_WAVE].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_ICY_WIND].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveAccuracy(MOVE_SWIFT) == 0); + ASSUME(GetMovePower(MOVE_SLAM) == GetMovePower(MOVE_STRENGTH)); + ASSUME(GetMovePower(MOVE_MEGA_KICK) > GetMovePower(MOVE_STRENGTH)); + ASSUME(GetMoveAccuracy(MOVE_SLAM) < GetMoveAccuracy(MOVE_STRENGTH)); + ASSUME(GetMoveAccuracy(MOVE_MEGA_KICK) < GetMoveAccuracy(MOVE_STRENGTH)); + ASSUME(GetMoveAccuracy(MOVE_TACKLE) == 100); + ASSUME(GetMoveAccuracy(MOVE_GUST) == 100); + ASSUME(GetMoveAccuracy(MOVE_SHOCK_WAVE) == 0); + ASSUME(GetMoveAccuracy(MOVE_THUNDERBOLT) == 100); + ASSUME(GetMoveAccuracy(MOVE_ICY_WIND) != 100); + ASSUME(GetMoveCategory(MOVE_SLAM) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_MEGA_KICK) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SHOCK_WAVE) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_ICY_WIND) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_THUNDERBOLT) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); OPPONENT(SPECIES_EXPLOUD) { Moves(move1, move2, move3, move4); Ability(abilityAtk); SpAttack(50); } // Low Sp.Atk, so Swift deals less damage than Strength. } WHEN { switch (turns) @@ -146,10 +146,10 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves which deal more damage instead of moves PARAMETRIZE { move1 = MOVE_POISON_JAB; move2 = MOVE_WATER_GUN; expectedMove = MOVE_POISON_JAB; abilityDef = ABILITY_IMMUNITY; turns = 3; } GIVEN { - ASSUME(gMovesInfo[MOVE_WATERFALL].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SCALD].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_POISON_JAB].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_WATERFALL) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SCALD) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_POISON_JAB) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_TYPHLOSION) { Ability(abilityDef); } PLAYER(SPECIES_WOBBUFFET); @@ -176,8 +176,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers Earthquake over Drill Run if both require the { // Drill Run has less accuracy than E-quake, but can score a higher crit. However the chance is too small, so AI should ignore it. GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion - ASSUME(gMovesInfo[MOVE_DRILL_RUN].category == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion + ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion + ASSUME(GetMoveCategory(MOVE_DRILL_RUN) == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_TYPHLOSION); PLAYER(SPECIES_WOBBUFFET); @@ -202,8 +202,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers a weaker move over a one with a downside effec PARAMETRIZE { move1 = MOVE_OVERHEAT; move2 = MOVE_FLAMETHROWER; hp = 250; expectedMove = MOVE_OVERHEAT; turns = 1; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLAMETHROWER].category == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet - ASSUME(gMovesInfo[MOVE_OVERHEAT].category == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet + ASSUME(GetMoveCategory(MOVE_FLAMETHROWER) == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet + ASSUME(GetMoveCategory(MOVE_OVERHEAT) == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(hp); } PLAYER(SPECIES_WOBBUFFET); @@ -242,8 +242,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves with the best possible score, chosen ran AI_SINGLE_BATTLE_TEST("AI can choose a status move that boosts the attack by two") { GIVEN { - ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_HORN_ATTACK].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_HORN_ATTACK) == DAMAGE_CATEGORY_PHYSICAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(277); }; PLAYER(SPECIES_WOBBUFFET); @@ -330,8 +330,8 @@ AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user PARAMETRIZE { } GIVEN { - ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SOLAR_BEAM) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_GRASS_PLEDGE) == DAMAGE_CATEGORY_SPECIAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(211); } PLAYER(SPECIES_WOBBUFFET); @@ -355,7 +355,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user AI_SINGLE_BATTLE_TEST("AI won't use ground type attacks against flying type Pokemon unless Gravity is in effect") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); // Otherwise, it doesn't KO Crobat + ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); // Otherwise, it doesn't KO Crobat AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_CROBAT); PLAYER(SPECIES_WOBBUFFET); @@ -430,7 +430,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not use a status move if partner already chose He for (j = MOVE_NONE + 1; j < MOVES_COUNT; j++) { - if (gMovesInfo[j].category == DAMAGE_CATEGORY_STATUS) { + if (GetMoveCategory(j) == DAMAGE_CATEGORY_STATUS) { PARAMETRIZE { statusMove = j; } } } @@ -509,9 +509,9 @@ AI_SINGLE_BATTLE_TEST("AI will choose either Rock Tomb or Bulldoze if Stat drop AI_SINGLE_BATTLE_TEST("First Impression is preferred on the first turn of the species if it's the best dmg move") { GIVEN { - ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].effect == EFFECT_FIRST_TURN_ONLY); - ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].power == 90); - ASSUME(gMovesInfo[MOVE_LUNGE].power == 80); + ASSUME(GetMoveEffect(MOVE_FIRST_IMPRESSION) == EFFECT_FIRST_TURN_ONLY); + ASSUME(GetMovePower(MOVE_FIRST_IMPRESSION) == 90); + ASSUME(GetMovePower(MOVE_LUNGE) == 80); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_KANGASKHAN); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_FIRST_IMPRESSION, MOVE_LUNGE); } @@ -531,9 +531,9 @@ AI_SINGLE_BATTLE_TEST("First Impression is not chosen if it's blocked by certain PARAMETRIZE { species = SPECIES_TSAREENA; ability = ABILITY_QUEENLY_MAJESTY; } GIVEN { - ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].effect == EFFECT_FIRST_TURN_ONLY); - ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].power == 90); - ASSUME(gMovesInfo[MOVE_LUNGE].power == 80); + ASSUME(GetMoveEffect(MOVE_FIRST_IMPRESSION) == EFFECT_FIRST_TURN_ONLY); + ASSUME(GetMovePower(MOVE_FIRST_IMPRESSION) == 90); + ASSUME(GetMovePower(MOVE_LUNGE) == 80); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_FIRST_IMPRESSION, MOVE_LUNGE); } @@ -545,7 +545,7 @@ AI_SINGLE_BATTLE_TEST("First Impression is not chosen if it's blocked by certain AI_SINGLE_BATTLE_TEST("AI will not choose Burn Up if the user lost the Fire typing") { GIVEN { - ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_CYNDAQUIL) { Moves(MOVE_BURN_UP, MOVE_EXTRASENSORY, MOVE_FLAMETHROWER); } @@ -559,7 +559,7 @@ AI_SINGLE_BATTLE_TEST("AI will only choose Surf 1/3 times if the opposing mon ha { PASSES_RANDOMLY(1, 3, RNG_AI_ABILITY); GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }; OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); } @@ -576,7 +576,7 @@ AI_SINGLE_BATTLE_TEST("AI will choose Thunderbolt then Surf 2/3 times if the opp { PASSES_RANDOMLY(2, 3, RNG_AI_ABILITY); GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }; OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); } @@ -596,10 +596,10 @@ AI_SINGLE_BATTLE_TEST("AI will choose Scratch over Power-up Punch with Contrary" PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; } PARAMETRIZE {ability = ABILITY_CONTRARY; } GIVEN { - ASSUME(gMovesInfo[MOVE_SCRATCH].power == 40); - ASSUME(gMovesInfo[MOVE_SCRATCH].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].power == 40); - ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].type == TYPE_FIGHTING); + ASSUME(GetMovePower(MOVE_SCRATCH) == 40); + ASSUME(GetMoveType(MOVE_SCRATCH) == TYPE_NORMAL); + ASSUME(GetMovePower(MOVE_POWER_UP_PUNCH) == 40); + ASSUME(GetMoveType(MOVE_POWER_UP_PUNCH) == TYPE_FIGHTING); ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER); ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); @@ -622,10 +622,10 @@ AI_SINGLE_BATTLE_TEST("AI will choose Superpower over Outrage with Contrary") PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; } PARAMETRIZE {ability = ABILITY_CONTRARY; } GIVEN { - ASSUME(gMovesInfo[MOVE_SUPERPOWER].power == 120); - ASSUME(gMovesInfo[MOVE_SUPERPOWER].type == TYPE_FIGHTING); - ASSUME(gMovesInfo[MOVE_OUTRAGE].power == 120); - ASSUME(gMovesInfo[MOVE_OUTRAGE].type == TYPE_DRAGON); + ASSUME(GetMovePower(MOVE_SUPERPOWER) == 120); + ASSUME(GetMoveType(MOVE_SUPERPOWER) == TYPE_FIGHTING); + ASSUME(GetMovePower(MOVE_OUTRAGE) == 120); + ASSUME(GetMoveType(MOVE_OUTRAGE) == TYPE_DRAGON); ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER); ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); @@ -650,7 +650,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not choose Earthquake if it damages the partner") PARAMETRIZE { species = SPECIES_CHIKORITA; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -667,7 +667,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not choose Earthquake if it damages the partner") AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if partner is not alive") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -682,7 +682,7 @@ AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if partner is not alive") AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if it kill an opposing mon and does 1/3 of damage to AI") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { HP(1); } @@ -700,7 +700,7 @@ AI_DOUBLE_BATTLE_TEST("AI will the see a corresponding absorbing ability on part PARAMETRIZE { ability = ABILITY_STATIC; } GIVEN { - ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -721,11 +721,11 @@ AI_SINGLE_BATTLE_TEST("AI calculates guaranteed criticals and detects critical i PARAMETRIZE { ability = ABILITY_SHELL_ARMOR; } GIVEN { - ASSUME(gMovesInfo[MOVE_STORM_THROW].alwaysCriticalHit); - ASSUME(gMovesInfo[MOVE_STORM_THROW].power == 60); - ASSUME(gMovesInfo[MOVE_BRICK_BREAK].power == 75); - ASSUME(gMovesInfo[MOVE_STORM_THROW].type == gMovesInfo[MOVE_BRICK_BREAK].type); - ASSUME(gMovesInfo[MOVE_STORM_THROW].category == gMovesInfo[MOVE_BRICK_BREAK].category); + ASSUME(MoveAlwaysCrits(MOVE_STORM_THROW)); + ASSUME(GetMovePower(MOVE_STORM_THROW) == 60); + ASSUME(GetMovePower(MOVE_BRICK_BREAK) == 75); + ASSUME(GetMoveType(MOVE_STORM_THROW) == GetMoveType(MOVE_BRICK_BREAK)); + ASSUME(GetMoveCategory(MOVE_STORM_THROW) == GetMoveCategory(MOVE_BRICK_BREAK)); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_OMASTAR) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_STORM_THROW, MOVE_BRICK_BREAK); } @@ -761,11 +761,11 @@ AI_SINGLE_BATTLE_TEST("AI avoids contact moves against rocky helmet") PARAMETRIZE { item = ITEM_ROCKY_HELMET; } GIVEN { - ASSUME(gMovesInfo[MOVE_BRANCH_POKE].makesContact); - ASSUME(!gMovesInfo[MOVE_LEAFAGE].makesContact); - ASSUME(gMovesInfo[MOVE_BRANCH_POKE].power == gMovesInfo[MOVE_LEAFAGE].power); - ASSUME(gMovesInfo[MOVE_BRANCH_POKE].type == gMovesInfo[MOVE_LEAFAGE].type); - ASSUME(gMovesInfo[MOVE_BRANCH_POKE].category == gMovesInfo[MOVE_LEAFAGE].category); + ASSUME(MoveMakesContact(MOVE_BRANCH_POKE)); + ASSUME(!MoveMakesContact(MOVE_LEAFAGE)); + ASSUME(GetMovePower(MOVE_BRANCH_POKE) == GetMovePower(MOVE_LEAFAGE)); + ASSUME(GetMoveType(MOVE_BRANCH_POKE) == GetMoveType(MOVE_LEAFAGE)); + ASSUME(GetMoveCategory(MOVE_BRANCH_POKE) == GetMoveCategory(MOVE_LEAFAGE)); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_WOBBUFFET) { Item(item); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BRANCH_POKE, MOVE_LEAFAGE); } @@ -785,11 +785,11 @@ AI_SINGLE_BATTLE_TEST("AI uses a guaranteed KO move instead of the move with the PARAMETRIZE { flags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT; } GIVEN { - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); - ASSUME(gMovesInfo[MOVE_SLASH].power == 70); - ASSUME(gMovesInfo[MOVE_STRENGTH].power == 80); - ASSUME(gMovesInfo[MOVE_SLASH].type == gMovesInfo[MOVE_STRENGTH].type); - ASSUME(gMovesInfo[MOVE_SLASH].category == gMovesInfo[MOVE_STRENGTH].category); + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); + ASSUME(GetMovePower(MOVE_SLASH) == 70); + ASSUME(GetMovePower(MOVE_STRENGTH) == 80); + ASSUME(GetMoveType(MOVE_SLASH) == GetMoveType(MOVE_STRENGTH)); + ASSUME(GetMoveCategory(MOVE_SLASH) == GetMoveCategory(MOVE_STRENGTH)); AI_FLAGS(flags); PLAYER(SPECIES_WOBBUFFET) { HP(225); } OPPONENT(SPECIES_ABSOL) { Ability(ABILITY_SUPER_LUCK); Moves(MOVE_SLASH, MOVE_STRENGTH); } @@ -818,10 +818,10 @@ AI_SINGLE_BATTLE_TEST("AI stays choice locked into moves in spite of the player' GIVEN { ASSUME(gItemsInfo[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND); - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); - ASSUME(gMovesInfo[MOVE_BOOMBURST].soundMove == TRUE); - ASSUME(gMovesInfo[MOVE_BULLET_SEED].ballisticMove == TRUE); - ASSUME(gMovesInfo[MOVE_TAIL_WHIP].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); + ASSUME(IsSoundMove(MOVE_BOOMBURST)); + ASSUME(IsBallisticMove(MOVE_BULLET_SEED)); + ASSUME(GetMoveCategory(MOVE_TAIL_WHIP) == DAMAGE_CATEGORY_STATUS); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(playerMon) { Ability(ability); } diff --git a/test/battle/ai/ai_calc_best_move_score.c b/test/battle/ai/ai_calc_best_move_score.c index bece527f30..f3b339deba 100644 --- a/test/battle/ai/ai_calc_best_move_score.c +++ b/test/battle/ai/ai_calc_best_move_score.c @@ -10,9 +10,9 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it PARAMETRIZE { move = MOVE_CALM_MIND; } GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85); - ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY); - ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND); + ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_CELEBRATE); }; OPPONENT(SPECIES_KANGASKHAN) { Speed(20); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); } @@ -30,9 +30,9 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it PARAMETRIZE { move = MOVE_CALM_MIND; } GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85); - ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY); - ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND); + ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_COMBUSKEN) { Speed(20); Moves(MOVE_DOUBLE_KICK, MOVE_CELEBRATE); }; OPPONENT(SPECIES_KANGASKHAN) { Speed(15); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); } @@ -62,9 +62,9 @@ AI_SINGLE_BATTLE_TEST("AI will correctly predict what move the opposing mon goin PARAMETRIZE { move = MOVE_CALM_MIND; } GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85); - ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY); - ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND); + ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_DOUBLE_KICK, MOVE_FLAME_WHEEL, MOVE_CELEBRATE); }; OPPONENT(SPECIES_KANGASKHAN) { Speed(20); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); } @@ -77,10 +77,10 @@ AI_SINGLE_BATTLE_TEST("AI will correctly predict what move the opposing mon goin AI_SINGLE_BATTLE_TEST("AI will not use Throat Chop if opposing mon has a better move") { GIVEN { - ASSUME(gMovesInfo[MOVE_PSYCHIC_FANGS].power == 85); - ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80); - ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].power == 40); - ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70); + ASSUME(GetMovePower(MOVE_PSYCHIC_FANGS) == 85); + ASSUME(GetMovePower(MOVE_THROAT_CHOP) == 80); + ASSUME(GetMovePower(MOVE_DISARMING_VOICE) == 40); + ASSUME(GetMovePower(MOVE_FLAME_BURST) == 70); ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_REGIROCK) { Speed(15); Moves(MOVE_DISARMING_VOICE, MOVE_FLAME_BURST); }; @@ -96,10 +96,10 @@ AI_SINGLE_BATTLE_TEST("AI will select Throat Chop if the sound move is the best { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE); - ASSUME(gMovesInfo[MOVE_PSYCHIC_FANGS].power == 85); - ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80); - ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70); - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].power == 90); + ASSUME(GetMovePower(MOVE_PSYCHIC_FANGS) == 85); + ASSUME(GetMovePower(MOVE_THROAT_CHOP) == 80); + ASSUME(GetMovePower(MOVE_FLAME_BURST) == 70); + ASSUME(GetMovePower(MOVE_HYPER_VOICE) == 90); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_REGIROCK) { Speed(15); Moves(MOVE_HYPER_VOICE, MOVE_FLAME_BURST); }; OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Moves(MOVE_THROAT_CHOP, MOVE_PSYCHIC_FANGS); } diff --git a/test/battle/ai/ai_check_viability.c b/test/battle/ai/ai_check_viability.c index 37ad7edb15..2c20a08db6 100644 --- a/test/battle/ai/ai_check_viability.c +++ b/test/battle/ai/ai_check_viability.c @@ -15,7 +15,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Facade") PARAMETRIZE { status1 = STATUS1_BURN; expectedMove = MOVE_FACADE; } GIVEN { - ASSUME(gMovesInfo[MOVE_FACADE].effect == EFFECT_FACADE); + ASSUME(GetMoveEffect(MOVE_FACADE) == EFFECT_FACADE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(60); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_FACADE); Status1(status1); } @@ -36,8 +36,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Smelling Salt") GIVEN { ASSUME(B_UPDATED_MOVE_DATA >= GEN_6); - ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].argument == STATUS1_PARALYSIS); + ASSUME(GetMoveEffect(MOVE_SMELLING_SALTS) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_SMELLING_SALTS) == STATUS1_PARALYSIS); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(60); Status1(status1); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_SMELLING_SALTS); } @@ -58,8 +58,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Wake Up Slap") GIVEN { ASSUME(B_UPDATED_MOVE_DATA >= GEN_6); - ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].argument == STATUS1_SLEEP); + ASSUME(GetMoveEffect(MOVE_WAKE_UP_SLAP) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_WAKE_UP_SLAP) == STATUS1_SLEEP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_MEGANIUM) { HP(35); Status1(status1); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_WAKE_UP_SLAP); } @@ -80,8 +80,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Grav Apple") PARAMETRIZE { movePlayer = MOVE_GRAVITY; expectedMove = MOVE_GRAV_APPLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_GRAV_APPLE].effect == EFFECT_GRAV_APPLE); - ASSUME(gMovesInfo[MOVE_GRAV_APPLE].power == gMovesInfo[MOVE_DRUM_BEATING].power); + ASSUME(GetMoveEffect(MOVE_GRAV_APPLE) == EFFECT_GRAV_APPLE); + ASSUME(GetMovePower(MOVE_GRAV_APPLE) == GetMovePower(MOVE_DRUM_BEATING)); ASSUME(MoveHasAdditionalEffect(MOVE_DRUM_BEATING, MOVE_EFFECT_SPD_MINUS_1) == TRUE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(81); Speed(20); } @@ -103,7 +103,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Flail") PARAMETRIZE { hp = 5; expectedMove = MOVE_FLAIL; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLAIL].effect == EFFECT_FLAIL); + ASSUME(GetMoveEffect(MOVE_FLAIL) == EFFECT_FLAIL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { Speed(10); } OPPONENT(SPECIES_WOBBUFFET) { HP(hp); MaxHP(490); Speed(20); Moves(MOVE_BODY_SLAM, MOVE_FLAIL); } @@ -134,8 +134,8 @@ AI_SINGLE_BATTLE_TEST("AI will only use Dream Eater if target is asleep") AI_SINGLE_BATTLE_TEST("AI sees increased base power of Spit Up") { GIVEN { - ASSUME(gMovesInfo[MOVE_STOCKPILE].effect == EFFECT_STOCKPILE); - ASSUME(gMovesInfo[MOVE_SPIT_UP].effect == EFFECT_SPIT_UP); + ASSUME(GetMoveEffect(MOVE_STOCKPILE) == EFFECT_STOCKPILE); + ASSUME(GetMoveEffect(MOVE_SPIT_UP) == EFFECT_SPIT_UP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(43); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_STOCKPILE, MOVE_SPIT_UP, MOVE_TACKLE); } @@ -155,10 +155,10 @@ AI_SINGLE_BATTLE_TEST("AI can choose Counter or Mirror Coat if the predicted mov PARAMETRIZE { playerMove = MOVE_POWER_GEM; opponentMove = MOVE_MIRROR_COAT; } GIVEN { - ASSUME(gMovesInfo[MOVE_COUNTER].effect == EFFECT_COUNTER); - ASSUME(gMovesInfo[MOVE_MIRROR_COAT].effect == EFFECT_MIRROR_COAT); - ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_POWER_GEM].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER); + ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT); + ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_POWER_GEM) == DAMAGE_CATEGORY_SPECIAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { HP(102); Speed(100); Moves(opponentMove, MOVE_STRENGTH); } @@ -202,7 +202,7 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner") PARAMETRIZE { status1_0 = STATUS1_NONE; status1_1 = STATUS1_PARALYSIS; partnerAbility = ABILITY_SOUNDPROOF; } GIVEN { - ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_8); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); @@ -226,7 +226,7 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members") PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SOUNDPROOF; } GIVEN { - ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_5); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); @@ -243,8 +243,8 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members") AI_DOUBLE_BATTLE_TEST("AI prioritizes Skill Swapping Contrary to allied mons that would benefit from it") { GIVEN { - ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); - ASSUME(gMovesInfo[MOVE_OVERHEAT].additionalEffects[0].moveEffect == MOVE_EFFECT_SP_ATK_MINUS_2); + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); + ASSUME(GetMoveAdditionalEffectById(MOVE_OVERHEAT, 0)->moveEffect == MOVE_EFFECT_SP_ATK_MINUS_2); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_DOUBLE_BATTLE); PLAYER(SPECIES_WOBBUFFET) { Speed(3); } PLAYER(SPECIES_WOBBUFFET) { Speed(3); } diff --git a/test/battle/ai/ai_choice.c b/test/battle/ai/ai_choice.c index c9992d2cab..f1f13a373e 100644 --- a/test/battle/ai/ai_choice.c +++ b/test/battle/ai/ai_choice.c @@ -25,8 +25,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon switch out after using a status move onc } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_RHYDON) OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); } @@ -60,7 +60,7 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use stat boosting moves") } GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].target == MOVE_TARGET_USER); + ASSUME(GetMoveTarget(MOVE_SWORDS_DANCE) == MOVE_TARGET_USER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_RHYDON) OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_SWORDS_DANCE, MOVE_TACKLE); Item(heldItem); Ability(ability); } @@ -94,8 +94,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they are the on } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_RHYDON) OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); } @@ -129,8 +129,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they don't have } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_RHYDON) OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); } @@ -164,8 +164,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they are trappe } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(species) { Ability(playerAbility); } OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(aiAbility); } diff --git a/test/battle/ai/ai_double_ace.c b/test/battle/ai/ai_double_ace.c index aec37b9307..5e49c0d6e1 100644 --- a/test/battle/ai/ai_double_ace.c +++ b/test/battle/ai/ai_double_ace.c @@ -2,8 +2,8 @@ #include "test/battle.h" ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_CRUNCH].type == TYPE_DARK); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveType(MOVE_CRUNCH) == TYPE_DARK); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC); } diff --git a/test/battle/ai/ai_flag_predict_ability.c b/test/battle/ai/ai_flag_predict_ability.c index ab934698b8..9d85773e3e 100644 --- a/test/battle/ai/ai_flag_predict_ability.c +++ b/test/battle/ai/ai_flag_predict_ability.c @@ -6,7 +6,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_WEIGH_ABILITY_PREDICTION: AI will predict opposin { PASSES_RANDOMLY(7, 14, RNG_AI_PREDICT_ABILITY); GIVEN { - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_WEIGH_ABILITY_PREDICTION); PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }; OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); } diff --git a/test/battle/ai/ai_flag_risky.c b/test/battle/ai/ai_flag_risky.c index 87be344ab8..bbc9a640a6 100644 --- a/test/battle/ai/ai_flag_risky.c +++ b/test/battle/ai/ai_flag_risky.c @@ -9,7 +9,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Mirror Coat against specia PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; } GIVEN { - ASSUME(gMovesInfo[MOVE_MIRROR_COAT].effect == EFFECT_MIRROR_COAT); + ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT); ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseSpAttack == 85); ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseAttack == 65); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); @@ -28,7 +28,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Counter against physical a PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; } GIVEN { - ASSUME(gMovesInfo[MOVE_COUNTER].effect == EFFECT_COUNTER); + ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER); ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseAttack == 85); ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseSpAttack == 60); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); @@ -47,7 +47,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will prioritize Revenge if slower") PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; } GIVEN { - ASSUME(gMovesInfo[MOVE_REVENGE].effect == EFFECT_REVENGE); + ASSUME(GetMoveEffect(MOVE_REVENGE) == EFFECT_REVENGE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); PLAYER(SPECIES_GROVYLE) { Level(20); Speed(4); Moves(MOVE_ENERGY_BALL); } OPPONENT(SPECIES_CASTFORM) { Level(19); Speed(3); Moves(MOVE_TACKLE, MOVE_REVENGE); } diff --git a/test/battle/ai/ai_flag_sequence_switching.c b/test/battle/ai/ai_flag_sequence_switching.c index 8502efbba7..56d7eb881f 100644 --- a/test/battle/ai/ai_flag_sequence_switching.c +++ b/test/battle/ai/ai_flag_sequence_switching.c @@ -48,8 +48,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: Roar and Dragon Tail still fo PASSES_RANDOMLY(1, 2, RNG_FORCE_RANDOM_SWITCH); GIVEN { - ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR); - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); AI_FLAGS(AI_FLAG_SEQUENCE_SWITCHING); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -82,10 +82,10 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lo } GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); - ASSUME(gMovesInfo[MOVE_CHILLY_RECEPTION].effect == EFFECT_CHILLY_RECEPTION); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_CHILLY_RECEPTION) == EFFECT_CHILLY_RECEPTION); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiSequenceSwitchingFlag); PLAYER(SPECIES_SWELLOW) { Level (50); } OPPONENT(SPECIES_MACHOP) { Level(1); Moves(move); } diff --git a/test/battle/ai/ai_powerful_status.c b/test/battle/ai/ai_powerful_status.c index 4a14c0bf80..99aff19384 100644 --- a/test/battle/ai/ai_powerful_status.c +++ b/test/battle/ai/ai_powerful_status.c @@ -5,8 +5,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers to set up a powerful Status over fainting a target") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_POWERFUL_STATUS); PLAYER(SPECIES_WOBBUFFET) { HP(1); } PLAYER(SPECIES_WYNAUT); @@ -23,8 +23,8 @@ AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up { GIVEN { ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_POWERFUL_STATUS | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_WOBBUFFET) { HP(1); Moves(MOVE_RAPID_SPIN, MOVE_DEFOG, MOVE_CELEBRATE); } PLAYER(SPECIES_WYNAUT); @@ -40,8 +40,8 @@ AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up AI_SINGLE_BATTLE_TEST("AI will not set up Rain if it is already raining") { GIVEN { - ASSUME(gMovesInfo[MOVE_RAIN_DANCE].effect == EFFECT_RAIN_DANCE); - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_POWERFUL_STATUS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 00caff5932..a4cd202574 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -93,7 +93,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not try to switch for the same pokemon for 2 spot AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: U-Turn will send out Ace Mon if it's the only one remaining") { GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_ACE_POKEMON); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); } @@ -168,11 +168,11 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI will not switch in a Pokemo PARAMETRIZE { speedAlakazm = 400; alakazamFirst = TRUE; aiSmartSwitchFlags = AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES; } // AI_FLAG_SMART_MON_CHOICES recognizes that Alakazam is faster and can KO, and will switch it in GIVEN { - ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_BUBBLE_BEAM].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_FOCUS_BLAST) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_BUBBLE_BEAM) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiSmartSwitchFlags); PLAYER(SPECIES_WEAVILE) { Speed(300); Ability(ABILITY_SHADOW_TAG); } // Weavile has Shadow Tag, so AI can't switch on the first turn, but has to do it after fainting. OPPONENT(SPECIES_KADABRA) { Speed(200); Moves(MOVE_PSYCHIC, MOVE_DISABLE, MOVE_TAUNT, MOVE_CALM_MIND); } @@ -250,7 +250,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize offensive options after slow U-Turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_FALSE_SWIPE].effect == EFFECT_FALSE_SWIPE); + ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_FALSE_SWIPE, MOVE_BOOMBURST); Speed(5); SpAttack(50); } OPPONENT(SPECIES_PONYTA) { Level(1); Moves(MOVE_U_TURN); Speed(4); } // Forces switchout @@ -265,7 +265,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize { GIVEN { ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON); - ASSUME(gMovesInfo[MOVE_FALSE_SWIPE].effect == EFFECT_FALSE_SWIPE); + ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_FALSE_SWIPE, MOVE_BOOMBURST); Speed(5); SpAttack(50); } OPPONENT(SPECIES_PONYTA) { Level(1); Item(ITEM_EJECT_BUTTON); Moves(MOVE_TACKLE); Speed(4); } // Forces switchout @@ -280,7 +280,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize { GIVEN { ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK); - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_GROWL, MOVE_BOOMBURST); Speed(5); SpAttack(50); } OPPONENT(SPECIES_PONYTA) { Level(1); Item(ITEM_EJECT_PACK); Moves(MOVE_TACKLE); Speed(4); } // Forces switchout @@ -337,7 +337,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches prioritize of AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches factor in Trick Room for revenge killing") { GIVEN { - ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM); + ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_SWELLOW) { Level(30); Speed(10); Moves(MOVE_WING_ATTACK, MOVE_GROWL); } OPPONENT(SPECIES_BALTOY) { Level(1); Speed(10); Moves(MOVE_TRICK_ROOM); } @@ -371,10 +371,10 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will not switch out if Pokemo PARAMETRIZE { move1 = MOVE_RAPID_SPIN; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_RAPID_SPIN].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_HEADBUTT].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_RAPID_SPIN) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_HEADBUTT) == DAMAGE_CATEGORY_PHYSICAL); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_HITMONTOP) { Level(30); Moves(MOVE_CHARM, MOVE_TACKLE, MOVE_STEALTH_ROCK, MOVE_EARTHQUAKE); Ability(ABILITY_INTIMIDATE); Speed(5); } OPPONENT(SPECIES_GRIMER) { Level(30); Moves(MOVE_TACKLE); Item(ITEM_FOCUS_SASH); Speed(4); } @@ -462,8 +462,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if mon would ASSUME(gSpeciesInfo[SPECIES_RHYDON].types[0] == TYPE_GROUND); ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[0] == TYPE_WATER); ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[1] == TYPE_FLYING); - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES); PLAYER(SPECIES_ELECTRODE) { Moves(MOVE_THUNDERBOLT, MOVE_THUNDER_WAVE, MOVE_THUNDER_SHOCK); } @@ -482,8 +482,8 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch out if it can't deal damage to ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[0] == ABILITY_WONDER_GUARD); ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[1] == ABILITY_NONE); ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[2] == ABILITY_NONE); - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_SHEDINJA) { Moves(MOVE_TACKLE); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -501,8 +501,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it can't d ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[0] == ABILITY_WONDER_GUARD); ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[1] == ABILITY_NONE); ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[2] == ABILITY_NONE); - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SHEDINJA) { Moves(MOVE_TACKLE); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -519,7 +519,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee PARAMETRIZE { species = SPECIES_HARIYAMA, odds = 50; } PASSES_RANDOMLY(odds, 100, RNG_AI_SWITCH_BADLY_POISONED); GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_TOXIC, MOVE_AURA_SPHERE); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -535,7 +535,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee { PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_CURSED); GIVEN { - ASSUME(gMovesInfo[MOVE_CURSE].effect == EFFECT_CURSE); + ASSUME(GetMoveEffect(MOVE_CURSE) == EFFECT_CURSE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_DUSCLOPS) { Moves(MOVE_FIRE_PUNCH, MOVE_CURSE); } PLAYER(SPECIES_MILOTIC) { Moves(MOVE_WATER_GUN); } @@ -551,7 +551,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee { PASSES_RANDOMLY(33, 100, RNG_AI_SWITCH_NIGHTMARE); GIVEN { - ASSUME(gMovesInfo[MOVE_NIGHTMARE].effect == EFFECT_NIGHTMARE); + ASSUME(GetMoveEffect(MOVE_NIGHTMARE) == EFFECT_NIGHTMARE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_GENGAR) { Moves(MOVE_NIGHTMARE); } OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); Status1(STATUS1_SLEEP); } @@ -566,7 +566,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee { PASSES_RANDOMLY(25, 100, RNG_AI_SWITCH_SEEDED); GIVEN { - ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED); + ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_WHIMSICOTT) { Moves(MOVE_LEECH_SEED); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -580,7 +580,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been infatuated") { GIVEN { - ASSUME(gMovesInfo[MOVE_ATTRACT].effect == EFFECT_ATTRACT); + ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_LUVDISC) { Moves(MOVE_ATTRACT); Gender(MON_FEMALE); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); Gender(MON_MALE); } @@ -597,7 +597,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee PARAMETRIZE { hp = 30; } PARAMETRIZE { hp = 10; } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_YAWN); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); HP(hp); MaxHP(30); } @@ -617,7 +617,7 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee PARAMETRIZE { hp = 30; } PARAMETRIZE { hp = 10; } GIVEN { - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_YAWN); } PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_YAWN); } @@ -637,7 +637,7 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is semi-invulnerable and it has an absorber") { GIVEN { - ASSUME(gMovesInfo[MOVE_DIVE].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_DIVE) == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_LUVDISC) { Moves(MOVE_DIVE); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -652,7 +652,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an { PASSES_RANDOMLY(33, 100, RNG_AI_SWITCH_ABSORBING); GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_LUVDISC) { Moves(MOVE_WATER_GUN); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SHOCK_WAVE); } @@ -667,7 +667,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m { PASSES_RANDOMLY(100, 100, RNG_AI_SWITCH_ABSORBING); GIVEN { - ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].type == TYPE_GRASS); + ASSUME(GetMoveType(MOVE_SOLAR_BEAM) == TYPE_GRASS); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_BELLOSSOM) { Moves(MOVE_SOLAR_BEAM); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -681,7 +681,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is charging and it has a good switchin immunity (type)") { GIVEN { - ASSUME(gMovesInfo[MOVE_DIG].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_DIG) == TYPE_GROUND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SANDSHREW) { Moves(MOVE_DIG); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -695,7 +695,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is charging and it has a good switchin immunity (ability)") { GIVEN { - ASSUME(gMovesInfo[MOVE_DIG].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_DIG) == TYPE_GROUND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SANDSHREW) { Moves(MOVE_DIG); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -723,7 +723,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an PARAMETRIZE { aiMon = SPECIES_ELECTRODE; absorbingAbility = ABILITY_SOUNDPROOF; move = MOVE_HYPER_VOICE;} GIVEN { ASSUME(B_REDIRECT_ABILITY_IMMUNITY >= GEN_5); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ZIGZAGOON) { Moves(move); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } @@ -741,8 +741,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if opponent u PARAMETRIZE { move = MOVE_FLY; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(gMovesInfo[MOVE_SKY_ATTACK].effect == EFFECT_TWO_TURNS_ATTACK); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveEffect(MOVE_SKY_ATTACK) == EFFECT_TWO_TURNS_ATTACK); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_SWELLOW) { Moves(move); } OPPONENT(SPECIES_MILOTIC) { Moves(MOVE_SURF); } @@ -783,7 +783,7 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch out if it has <= 66% HP remaini AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Encore'd into a status move") { GIVEN { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); } OPPONENT(SPECIES_ODDISH) { Moves(MOVE_TOXIC, MOVE_SWEET_SCENT, MOVE_INGRAIN, MOVE_TACKLE); } @@ -797,7 +797,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will stay in if Encore'd into super effective move") { GIVEN { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); } OPPONENT(SPECIES_ODDISH) { Moves(MOVE_ACID); } @@ -813,7 +813,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if Encore'd i KNOWN_FAILING; // AI still switches even if ShouldSwitch is set to immediately return FALSE, something external seems to be triggering this PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_ENCORE); GIVEN { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); } OPPONENT(SPECIES_ODDISH) { Moves(MOVE_TACKLE); } @@ -859,8 +859,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac PARAMETRIZE {move = MOVE_EERIE_IMPULSE; aiSpecies = SPECIES_ESPEON; aiMove = MOVE_CONFUSION; }; GIVEN { - ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); - ASSUME(gMovesInfo[MOVE_EERIE_IMPULSE].effect == EFFECT_SPECIAL_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_EERIE_IMPULSE) == EFFECT_SPECIAL_ATTACK_DOWN_2); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ARON) { Moves(move, MOVE_TACKLE); } OPPONENT(aiSpecies) { Moves(aiMove); } @@ -880,8 +880,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac PARAMETRIZE {move = MOVE_CONFIDE; move2 = MOVE_EERIE_IMPULSE; aiSpecies = SPECIES_ESPEON; aiMove = MOVE_STORED_POWER; }; GIVEN { - ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); - ASSUME(gMovesInfo[MOVE_EERIE_IMPULSE].effect == EFFECT_SPECIAL_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_EERIE_IMPULSE) == EFFECT_SPECIAL_ATTACK_DOWN_2); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ARON) { Moves(move, move2, MOVE_TACKLE); } OPPONENT(aiSpecies) { Moves(aiMove); } @@ -924,3 +924,61 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI correctly handles abilities TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_ABSORB); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch out if Yawn'd with only Ace mon remaining") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING); + PLAYER(SPECIES_SLOWKING) { Moves(MOVE_YAWN, MOVE_CONFUSION, MOVE_POWER_GEM, MOVE_WATER_PULSE); Item(ITEM_LEFTOVERS); } + OPPONENT(SPECIES_SCOLIPEDE) { Moves(MOVE_POISON_TAIL); } + OPPONENT(SPECIES_ABSOL) { Moves(MOVE_KNOCK_OFF, MOVE_CRUNCH); } + } WHEN { + TURN { MOVE(player, MOVE_YAWN); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); } + if (aceFlag) + TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); } + else + TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_SWITCH(opponent, 1); } + } +} + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch in ace mon after U-Turn if other options available") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); } + OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); } + OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); } + } WHEN { + if (aceFlag) + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); } + else + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); } + } +} + +AI_SINGLE_BATTLE_TEST("Switch AI: AI won't switch in ace mon after U-Turn if other options available") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); } + OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); } + OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); } + } WHEN { + if (aceFlag) + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); } + else + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); } + } +} diff --git a/test/battle/ai/ai_trytofaint.c b/test/battle/ai/ai_trytofaint.c index 10eca2d676..a1a23efdec 100644 --- a/test/battle/ai/ai_trytofaint.c +++ b/test/battle/ai/ai_trytofaint.c @@ -5,7 +5,7 @@ AI_SINGLE_BATTLE_TEST("AI prefers priority moves if it's slower and can kill target") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(100); } PLAYER(SPECIES_WOBBUFFET) { Speed(100); } @@ -20,7 +20,7 @@ AI_SINGLE_BATTLE_TEST("AI prefers priority moves if it's slower and can kill tar AI_SINGLE_BATTLE_TEST("AI will choose a random move if it's faster and can kill target") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(1); } PLAYER(SPECIES_WOBBUFFET) { Speed(1); } @@ -35,7 +35,7 @@ AI_SINGLE_BATTLE_TEST("AI will choose a random move if it's faster and can kill AI_SINGLE_BATTLE_TEST("AI will choose a priority move if it is slower then the target and will be killed") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { Speed(100); } OPPONENT(SPECIES_WOBBUFFET) { HP(60); Speed(1); Moves(MOVE_QUICK_ATTACK, MOVE_STRENGTH); } diff --git a/test/battle/crit_chance.c b/test/battle/crit_chance.c index 69086acbe3..32c4c3380d 100644 --- a/test/battle/crit_chance.c +++ b/test/battle/crit_chance.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Side effected by Lucky Chant blocks critical hits") { GIVEN { - ASSUME(gMovesInfo[MOVE_LUCKY_CHANT].effect == EFFECT_LUCKY_CHANT); + ASSUME(GetMoveEffect(MOVE_LUCKY_CHANT) == EFFECT_LUCKY_CHANT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Flag ignoresTargetAbility ignores Battle Armor PARAMETRIZE { species = SPECIES_ARMALDO; ability = ABILITY_BATTLE_ARMOR; } GIVEN { - ASSUME(gMovesInfo[MOVE_SUNSTEEL_STRIKE].ignoresTargetAbility == TRUE); + ASSUME(MoveIgnoresTargetAbility(MOVE_SUNSTEEL_STRIKE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { @@ -100,7 +100,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Mold Breaker, Teravolt and Turboblaze ignore Ba SINGLE_BATTLE_TEST("Crit Chance: User effected by Laser Focus causes moves to result in a critical hit") { GIVEN { - ASSUME(gMovesInfo[MOVE_LASER_FOCUS].effect == EFFECT_LASER_FOCUS); + ASSUME(GetMoveEffect(MOVE_LASER_FOCUS) == EFFECT_LASER_FOCUS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -131,7 +131,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases the user's critical hit PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); + ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -149,7 +149,7 @@ SINGLE_BATTLE_TEST("Crit Chance: High crit rate increases the critical hit ratio PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -195,7 +195,7 @@ SINGLE_BATTLE_TEST("Crit Chance: High crit rate, Super Luck and Scope Lens cause { GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS); PLAYER(SPECIES_TOGEKISS) { Ability(ABILITY_SUPER_LUCK); Item(ITEM_SCOPE_LENS); }; OPPONENT(SPECIES_WOBBUFFET); @@ -257,8 +257,8 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by tw PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); - ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); + ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -271,76 +271,3 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by tw MESSAGE("A critical hit!"); } } - -SINGLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails in a single battle") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_DRAGON_CHEER); } - } SCENE { - MESSAGE("But it failed!"); - } -} - -DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by one on non Dragon types") -{ - PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); - GIVEN { - ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); - ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WYNAUT); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); - MESSAGE("Wynaut is getting pumped!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); - MESSAGE("A critical hit!"); - } -} - -DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by two on Dragon types") -{ - PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); - GIVEN { - ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); - ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_DRATINI); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); - MESSAGE("Dratini is getting pumped!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); - MESSAGE("A critical hit!"); - } -} - -DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails if critical hit stage was already increased by Focus Energy") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); - ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY); - ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(playerLeft, MOVE_FOCUS_ENERGY); MOVE(playerRight, MOVE_DRAGON_CHEER, target: playerLeft); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, playerLeft); - MESSAGE("But it failed!"); - } -} diff --git a/test/battle/damage_formula.c b/test/battle/damage_formula.c index 049bbf4051..0679725510 100644 --- a/test/battle/damage_formula.c +++ b/test/battle/damage_formula.c @@ -24,7 +24,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+") PARAMETRIZE { expectedDamage = 168; } PARAMETRIZE { expectedDamage = 168; } GIVEN { - ASSUME(gMovesInfo[MOVE_ICE_FANG].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_ICE_FANG) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_GLACEON) { Level(75); Attack(123); } OPPONENT(SPECIES_GARCHOMP) { Defense(163); } } WHEN { @@ -62,7 +62,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Muscle Band, crit)") PARAMETRIZE { expectedDamage = 276; } PARAMETRIZE { expectedDamage = 268; } GIVEN { - ASSUME(gMovesInfo[MOVE_ICE_FANG].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_ICE_FANG) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_GLACEON) { Level(75); Attack(123); Item(ITEM_MUSCLE_BAND); } OPPONENT(SPECIES_GARCHOMP) { Defense(163); } } WHEN { @@ -100,7 +100,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Marshadow vs Mawile)") PARAMETRIZE { expectedDamage = 124; } PARAMETRIZE { expectedDamage = 123; } GIVEN { - ASSUME(gMovesInfo[MOVE_SPECTRAL_THIEF].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SPECTRAL_THIEF) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_MARSHADOW) { Level(100); Attack(286); } OPPONENT(SPECIES_MAWILE) { Level(100); Defense(226); HP(241); } } WHEN { @@ -248,10 +248,10 @@ DOUBLE_BATTLE_TEST("Transistor Damage calculation", s16 damage) } } GIVEN { - ASSUME(gMovesInfo[MOVE_WILD_CHARGE].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_WILD_CHARGE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveType(MOVE_WILD_CHARGE) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetMoveCategory(MOVE_WILD_CHARGE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_THUNDER_SHOCK) == DAMAGE_CATEGORY_SPECIAL); ASSUME(NUM_DAMAGE_SPREADS == 16); PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_KLUTZ); } diff --git a/test/battle/form_change/mega_evolution.c b/test/battle/form_change/mega_evolution.c index 4c97c2c151..3d9d9cf507 100644 --- a/test/battle/form_change/mega_evolution.c +++ b/test/battle/form_change/mega_evolution.c @@ -108,7 +108,7 @@ SINGLE_BATTLE_TEST("Abilities replaced by Mega Evolution do not affect turn orde DOUBLE_BATTLE_TEST("Mega Evolution happens after switching, but before Focus Punch-like Moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH); + ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE); } OPPONENT(SPECIES_WYNAUT); @@ -157,7 +157,7 @@ SINGLE_BATTLE_TEST("Regular Mega Evolution and Fervent Wish Mega Evolution can h SINGLE_BATTLE_TEST("Mega Evolved Pokemon do not change abilities after fainting") { GIVEN { - ASSUME(gMovesInfo[MOVE_CRUNCH].makesContact == TRUE); + ASSUME(MoveMakesContact(MOVE_CRUNCH) == TRUE); ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[0] != ABILITY_ROUGH_SKIN); ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[1] != ABILITY_ROUGH_SKIN); ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[2] != ABILITY_ROUGH_SKIN); diff --git a/test/battle/form_change/primal_reversion.c b/test/battle/form_change/primal_reversion.c index d4e682e8de..d7d956d64b 100644 --- a/test/battle/form_change/primal_reversion.c +++ b/test/battle/form_change/primal_reversion.c @@ -120,7 +120,7 @@ DOUBLE_BATTLE_TEST("Primal reversion's order is determined by Speed - player fas SINGLE_BATTLE_TEST("Primal reversion happens after a mon is sent out after a mon is fainted") { GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET) {HP(1); } PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } OPPONENT(SPECIES_WOBBUFFET); @@ -156,7 +156,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a mon is switched in") SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Eject Button") { GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON); PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_EJECT_BUTTON); } PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } @@ -177,7 +177,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Eject B SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Red Card") { GIVEN { - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); ASSUME(gItemsInfo[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } @@ -197,7 +197,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Red Car SINGLE_BATTLE_TEST("Primal reversion happens after the entry hazards damage") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES); + ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } OPPONENT(SPECIES_WOBBUFFET); @@ -239,7 +239,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens immediately if it was brought in by DOUBLE_BATTLE_TEST("Primal reversion triggers for multiple battlers if multiple fainted the previous turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_CATERPIE) { HP(1); } PLAYER(SPECIES_RESHIRAM); @@ -262,8 +262,8 @@ DOUBLE_BATTLE_TEST("Primal reversion triggers for multiple battlers if multiple DOUBLE_BATTLE_TEST("Primal reversion triggers for all battlers if multiple fainted the previous turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); - ASSUME(gMovesInfo[MOVE_EXPLOSION].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); + ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_CATERPIE) { HP(1); } PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } @@ -290,11 +290,11 @@ DOUBLE_BATTLE_TEST("Primal reversion triggers for all battlers if multiple faint DOUBLE_BATTLE_TEST("Primal reversion and other switch-in effects trigger for all battlers if multiple fainted the previous turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); - ASSUME(gMovesInfo[MOVE_EXPLOSION].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); - ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES); - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); + ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_CATERPIE) { HP(1); } PLAYER(SPECIES_SCRAFTY) { Ability(ABILITY_INTIMIDATE); } diff --git a/test/battle/form_change/ultra_burst.c b/test/battle/form_change/ultra_burst.c index 8eb21866f3..640db3f881 100644 --- a/test/battle/form_change/ultra_burst.c +++ b/test/battle/form_change/ultra_burst.c @@ -74,7 +74,7 @@ SINGLE_BATTLE_TEST("Ultra Burst affects turn order") DOUBLE_BATTLE_TEST("Ultra Burst happens after switching, but before Focus Punch-like Moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH); + ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); } OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index abc9a11c4d..0d06268864 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -58,7 +58,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp) SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched") { GIVEN { - ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY); + ASSUME(GetMoveEffect(MOVE_FAKE_OUT) == EFFECT_FIRST_TURN_ONLY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -73,7 +73,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched") SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_HEAVY_SLAM].effect == EFFECT_HEAT_CRASH); + ASSUME(GetMoveEffect(MOVE_HEAVY_SLAM) == EFFECT_HEAT_CRASH); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -89,7 +89,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based mo SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO); + ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_MACHAMP) { Ability(ABILITY_NO_GUARD); } } WHEN { @@ -102,22 +102,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves") } } -// can't be used at all in Raid, see "Documenting Dynamax" -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; - OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); } - } WHEN { - TURN { MOVE(opponent, MOVE_DESTINY_BOND); MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); } - } SCENE { - MESSAGE("The opposing Wobbuffet used Destiny Bond!"); - MESSAGE("Wobbuffet used Max Strike!"); - MESSAGE("The opposing Wobbuffet fainted!"); - NONE_OF { HP_BAR(player); } - } -} - SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge") { GIVEN { @@ -136,8 +120,8 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge") SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves, but still take damage") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); - ASSUME(gMovesInfo[MOVE_WHIRLWIND].effect == EFFECT_ROAR); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_WHIRLWIND) == EFFECT_ROAR); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -158,7 +142,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing move SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves but no block message is printed if they faint") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); PLAYER(SPECIES_WOBBUFFET) { HP(1); }; PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -243,41 +227,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed o } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); } - TURN { MOVE(player, MOVE_EMBER); } - } SCENE { - MESSAGE("Wobbuffet used Max Strike!"); - MESSAGE("The opposing Wobbuffet used Encore!"); - MESSAGE("But it failed!"); - MESSAGE("Wobbuffet used Max Flare!"); - } -} - -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary - OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; - } WHEN { - TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); } - TURN { MOVE(player, MOVE_ARM_THRUST); } - TURN { MOVE(player, MOVE_ARM_THRUST); } - TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); } - } SCENE { - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("The opposing Wobbuffet used Encore!"); - MESSAGE("Wobbuffet used Arm Thrust!"); - } -} - // Max Moves don't make contact, so Cursed Body doesn't need to be tested, but it is coded for. SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled") { @@ -362,24 +311,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes") } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon take double damage from Dynamax Cannon", s16 damage) -{ - u32 dynamax; - PARAMETRIZE { dynamax = GIMMICK_NONE; } - PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } - GIVEN { - ASSUME(gMovesInfo[MOVE_DYNAMAX_CANNON].effect == EFFECT_DYNAMAX_DOUBLE_DMG); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_DYNAMAX_CANNON); } - } SCENE { - HP_BAR(player, captureDamage: &results[i].damage); - } FINALLY { - EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); - } -} - SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 damage) { bool32 protected; @@ -531,7 +462,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Endeavor uses a Pokemon's non-Dynamax HP", s16 dam PARAMETRIZE { dynamax = GIMMICK_NONE; } PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } GIVEN { - ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR); + ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR); PLAYER(SPECIES_WOBBUFFET) { Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); } } WHEN { @@ -550,7 +481,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Super Fang uses a Pokemon's non-Dynamax HP", s16 d PARAMETRIZE { dynamax = GIMMICK_NONE; } PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } GIVEN { - ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG); + ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_SUPER_FANG); PLAYER(SPECIES_WOBBUFFET) { Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { Speed(100); } } WHEN { @@ -569,7 +500,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Pain Split uses a Pokemon's non-Dynamax HP", s16 d PARAMETRIZE { dynamax = GIMMICK_NONE; } PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } GIVEN { - ASSUME(gMovesInfo[MOVE_PAIN_SPLIT].effect == EFFECT_PAIN_SPLIT); + ASSUME(GetMoveEffect(MOVE_PAIN_SPLIT) == EFFECT_PAIN_SPLIT); PLAYER(SPECIES_WOBBUFFET) { Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); } } WHEN { @@ -608,7 +539,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Heal Pulse heals based on a Pokemon's non-Dynamax PARAMETRIZE { dynamax = GIMMICK_NONE; } PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } GIVEN { - ASSUME(gMovesInfo[MOVE_HEAL_PULSE].effect == EFFECT_HEAL_PULSE); + ASSUME(GetMoveEffect(MOVE_HEAL_PULSE) == EFFECT_HEAL_PULSE); PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); Speed(100); } } WHEN { @@ -626,7 +557,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed") { GIVEN { // Fails?: ASSUME(GetMaxMove(B_POSITION_PLAYER_LEFT, MOVE_TACKLE) == MOVE_MAX_STRIKE); - ASSUME(gMovesInfo[MOVE_MAX_STRIKE].argument == MAX_EFFECT_LOWER_SPEED); + ASSUME(GetMoveMaxEffect(MOVE_MAX_STRIKE) == MAX_EFFECT_LOWER_SPEED); OPPONENT(SPECIES_WOBBUFFET) { Speed(100); } PLAYER(SPECIES_WOBBUFFET) { Speed(80); } } WHEN { @@ -650,7 +581,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed") DOUBLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers both opponents' speed") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_STRIKE].argument == MAX_EFFECT_LOWER_SPEED); + ASSUME(GetMoveMaxEffect(MOVE_MAX_STRIKE) == MAX_EFFECT_LOWER_SPEED); PLAYER(SPECIES_WOBBUFFET) { Speed(80); } PLAYER(SPECIES_WOBBUFFET) { Speed(79); } OPPONENT(SPECIES_WOBBUFFET) {Speed(100); } @@ -687,9 +618,9 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack") { s16 damage[4]; GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_KNUCKLE].argument == MAX_EFFECT_RAISE_TEAM_ATTACK); - ASSUME(gMovesInfo[MOVE_CLOSE_COMBAT].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveMaxEffect(MOVE_MAX_KNUCKLE) == MAX_EFFECT_RAISE_TEAM_ATTACK); + ASSUME(GetMoveCategory(MOVE_CLOSE_COMBAT) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -729,7 +660,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack") SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_FLARE].argument == MAX_EFFECT_SUN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_FLARE) == MAX_EFFECT_SUN); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -745,7 +676,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight") SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_GEYSER].argument == MAX_EFFECT_RAIN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_GEYSER) == MAX_EFFECT_RAIN); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -761,7 +692,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain") SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_HAILSTORM].argument == MAX_EFFECT_HAIL); + ASSUME(GetMoveMaxEffect(MOVE_MAX_HAILSTORM) == MAX_EFFECT_HAIL); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -777,7 +708,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail") SINGLE_BATTLE_TEST("(DYNAMAX) Max Rockfall sets up a sandstorm") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_ROCKFALL].argument == MAX_EFFECT_SANDSTORM); + ASSUME(GetMoveMaxEffect(MOVE_MAX_ROCKFALL) == MAX_EFFECT_SANDSTORM); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -794,7 +725,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain") { s32 maxHP = 490; // Because of recalculated stats upon Dynamaxing GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_OVERGROWTH].argument == MAX_EFFECT_GRASSY_TERRAIN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_OVERGROWTH) == MAX_EFFECT_GRASSY_TERRAIN); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseHP == 190); OPPONENT(SPECIES_WOBBUFFET) { MaxHP(maxHP); HP(maxHP / 2); }; PLAYER(SPECIES_WOBBUFFET) { MaxHP(maxHP); HP(maxHP / 2); }; @@ -814,7 +745,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain") SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_MINDSTORM].argument == MAX_EFFECT_PSYCHIC_TERRAIN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_MINDSTORM) == MAX_EFFECT_PSYCHIC_TERRAIN); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -831,7 +762,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain") SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_LIGHTNING].argument == MAX_EFFECT_ELECTRIC_TERRAIN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_LIGHTNING) == MAX_EFFECT_ELECTRIC_TERRAIN); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -846,7 +777,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain") SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain") { GIVEN { - ASSUME(gMovesInfo[MOVE_MAX_STARFALL].argument == MAX_EFFECT_MISTY_TERRAIN); + ASSUME(GetMoveMaxEffect(MOVE_MAX_STARFALL) == MAX_EFFECT_MISTY_TERRAIN); OPPONENT(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); } WHEN { @@ -861,7 +792,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain") SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_STONESURGE].argument == MAX_EFFECT_STEALTH_ROCK); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STONESURGE) == MAX_EFFECT_STEALTH_ROCK); PLAYER(SPECIES_DREDNAW) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -881,7 +812,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks") SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Steelsurge sets up sharp steel") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_STEELSURGE].argument == MAX_EFFECT_STEELSURGE); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STEELSURGE) == MAX_EFFECT_STEELSURGE); PLAYER(SPECIES_COPPERAJAH) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_HATTERENE); @@ -912,7 +843,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili PARAMETRIZE { move = MOVE_WATER_GUN; } PARAMETRIZE { move = MOVE_HYDRO_CANNON; } GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_HYDROSNIPE].argument == MAX_EFFECT_FIXED_POWER); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_HYDROSNIPE) == MAX_EFFECT_FIXED_POWER); PLAYER(SPECIES_INTELEON) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_ARCTOVISH) { Ability(ABILITY_WATER_ABSORB); } } WHEN { @@ -928,7 +859,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Volt Crash paralyzes both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_VOLT_CRASH].argument == MAX_EFFECT_PARALYZE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_VOLT_CRASH) == MAX_EFFECT_PARALYZE_FOES); PLAYER(SPECIES_PIKACHU) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_PICHU); OPPONENT(SPECIES_WOBBUFFET); @@ -955,7 +886,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = STATUS1_PARALYSIS; } PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = STATUS1_POISON; } GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STUN_SHOCK) == MAX_EFFECT_POISON_PARALYZE_FOES); PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_TOXEL); OPPONENT(SPECIES_WOBBUFFET); @@ -992,7 +923,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock chooses statuses before considering immunities") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STUN_SHOCK) == MAX_EFFECT_POISON_PARALYZE_FOES); PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_TOXEL); OPPONENT(SPECIES_GARBODOR); @@ -1025,7 +956,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = STATUS1_POISON; } PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = STATUS1_SLEEP; } GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_BEFUDDLE].argument == MAX_EFFECT_EFFECT_SPORE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_BEFUDDLE) == MAX_EFFECT_EFFECT_SPORE_FOES); PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_CATERPIE); OPPONENT(SPECIES_WOBBUFFET); @@ -1069,7 +1000,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and generates money") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_GOLD_RUSH].argument == MAX_EFFECT_CONFUSE_FOES_PAY_DAY); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_GOLD_RUSH) == MAX_EFFECT_CONFUSE_FOES_PAY_DAY); PLAYER(SPECIES_MEOWTH) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_PERSIAN); OPPONENT(SPECIES_WOBBUFFET); @@ -1089,7 +1020,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and genera DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_SMITE].argument == MAX_EFFECT_CONFUSE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SMITE) == MAX_EFFECT_CONFUSE_FOES); PLAYER(SPECIES_HATTERENE) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_HATENNA); OPPONENT(SPECIES_WOBBUFFET); @@ -1108,7 +1039,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents") DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possible") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_CUDDLE].argument == MAX_EFFECT_INFATUATE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CUDDLE) == MAX_EFFECT_INFATUATE_FOES); PLAYER(SPECIES_EEVEE) { Gender(MON_MALE); GigantamaxFactor(TRUE); } PLAYER(SPECIES_EEVEE); OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); } @@ -1129,7 +1060,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possibl DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Terror traps both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_TERROR].argument == MAX_EFFECT_MEAN_LOOK); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_TERROR) == MAX_EFFECT_MEAN_LOOK); PLAYER(SPECIES_GENGAR) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_GASTLY); OPPONENT(SPECIES_WOBBUFFET); @@ -1150,7 +1081,7 @@ TO_DO_BATTLE_TEST("(DYNAMAX) Baton Pass passes G-Max Terror's escape prevention DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Meltdown torments both opponents for 3 turns") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_MELTDOWN].argument == MAX_EFFECT_TORMENT_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_MELTDOWN) == MAX_EFFECT_TORMENT_FOES); PLAYER(SPECIES_MELMETAL) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_MELTAN); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SPLASH, MOVE_CELEBRATE); } @@ -1187,7 +1118,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Wildfire sets a field effect that damages no { s16 damage; GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_WILDFIRE].argument == MAX_EFFECT_WILDFIRE); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_WILDFIRE) == MAX_EFFECT_WILDFIRE); PLAYER(SPECIES_CHARIZARD) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_CHARMANDER); OPPONENT(SPECIES_WOBBUFFET) { HP(600); MaxHP(600); } @@ -1233,7 +1164,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of t { PASSES_RANDOMLY(1, 2, RNG_G_MAX_REPLENISH); GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_REPLENISH].argument == MAX_EFFECT_RECYCLE_BERRIES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_REPLENISH) == MAX_EFFECT_RECYCLE_BERRIES); PLAYER(SPECIES_SNORLAX) { Item(ITEM_APICOT_BERRY); GigantamaxFactor(TRUE); } PLAYER(SPECIES_MUNCHLAX) { Item(ITEM_APICOT_BERRY); Ability(ABILITY_THICK_FAT); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); } @@ -1261,8 +1192,8 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Snooze makes only the target drowsy") { PASSES_RANDOMLY(1, 2, RNG_G_MAX_SNOOZE); GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_SNOOZE].argument == MAX_EFFECT_YAWN_FOE); - ASSUME(gMovesInfo[MOVE_DARK_PULSE].category == DAMAGE_CATEGORY_SPECIAL); // Otherwise, Blissey faints. + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SNOOZE) == MAX_EFFECT_YAWN_FOE); + ASSUME(GetMoveCategory(MOVE_DARK_PULSE) == DAMAGE_CATEGORY_SPECIAL); // Otherwise, Blissey faints. PLAYER(SPECIES_GRIMMSNARL) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_IMPIDIMP); OPPONENT(SPECIES_BLISSEY); @@ -1285,7 +1216,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") { s16 damage1, damage2; GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_FINALE].argument == MAX_EFFECT_HEAL_TEAM); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_FINALE) == MAX_EFFECT_HEAL_TEAM); PLAYER(SPECIES_ALCREMIE) { HP(1); GigantamaxFactor(TRUE); } PLAYER(SPECIES_MILCERY) { HP(1); } OPPONENT(SPECIES_WOBBUFFET); @@ -1305,7 +1236,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_SWEETNESS].argument == MAX_EFFECT_AROMATHERAPY); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SWEETNESS) == MAX_EFFECT_AROMATHERAPY); PLAYER(SPECIES_APPLETUN) { Status1(STATUS1_POISON); GigantamaxFactor(TRUE); } PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } OPPONENT(SPECIES_WOBBUFFET); @@ -1325,7 +1256,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Centiferno traps both opponents in Fire Spin") { GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_CENTIFERNO].argument == MAX_EFFECT_FIRE_SPIN_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CENTIFERNO) == MAX_EFFECT_FIRE_SPIN_FOES); PLAYER(SPECIES_CENTISKORCH) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_SIZZLIPEDE); PLAYER(SPECIES_SIZZLIPEDE); @@ -1354,7 +1285,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Chi Strike boosts allies' crit chance") u32 j; GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_6); - ASSUME(gMovesInfo[MOVE_G_MAX_CHI_STRIKE].argument == MAX_EFFECT_CRIT_PLUS); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CHI_STRIKE) == MAX_EFFECT_CRIT_PLUS); PLAYER(SPECIES_MACHAMP) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_MACHOP); OPPONENT(SPECIES_WOBBUFFET); @@ -1385,8 +1316,8 @@ TO_DO_BATTLE_TEST("(DYNAMAX) Baton Pass doesn't pass G-Max Chi Strike's effect") DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Depletion takes away 2 PP from the target's last move") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].category == DAMAGE_CATEGORY_PHYSICAL); // Otherwise Sableye faints. - ASSUME(gMovesInfo[MOVE_G_MAX_DEPLETION].argument == MAX_EFFECT_SPITE); + ASSUME(GetMoveCategory(MOVE_DRAGON_CLAW) == DAMAGE_CATEGORY_PHYSICAL); // Otherwise Sableye faints. + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_DEPLETION) == MAX_EFFECT_SPITE); PLAYER(SPECIES_DURALUDON) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_WYNAUT); // Dynamax behaves weird with test turn order because stats are recalculated. @@ -1408,7 +1339,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage" PARAMETRIZE { protect = TRUE; } PARAMETRIZE { protect = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_G_MAX_ONE_BLOW].argument == MAX_EFFECT_BYPASS_PROTECT); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_ONE_BLOW) == MAX_EFFECT_BYPASS_PROTECT); PLAYER(SPECIES_URSHIFU) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_KUBFU); OPPONENT(SPECIES_WOBBUFFET); @@ -1431,6 +1362,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage" } // Bug Testing +// This test will fail if it's the first test a thread runs DOUBLE_BATTLE_TEST("(DYNAMAX) Max Flare doesn't softlock the game when fainting player partner") { GIVEN { @@ -1465,7 +1397,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't execute effects on fainted battler SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves fainting opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_WATERFALL].power > 0); + ASSUME(GetMovePower(MOVE_WATERFALL) > 0); PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_MOXIE); } OPPONENT(SPECIES_WOBBUFFET) { HP(1); } OPPONENT(SPECIES_WYNAUT); @@ -1507,11 +1439,11 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass absorbing abilities") PARAMETRIZE { move = MOVE_VINE_WHIP; ability = ABILITY_SAP_SIPPER; species = SPECIES_MILTANK; } GIVEN { - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_MUD_BOMB].type == TYPE_GROUND); - ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); + ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_MUD_BOMB) == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index a9e8fca871..709e658c38 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing boosts moves of the same type to 60 BP PARAMETRIZE { tera = GIMMICK_NONE; } PARAMETRIZE { tera = GIMMICK_TERA; } GIVEN { - ASSUME(gMovesInfo[MOVE_ABSORB].power == 20); + ASSUME(GetMovePower(MOVE_ABSORB) == 20); PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_GRASS); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -113,7 +113,7 @@ SINGLE_BATTLE_TEST("(TERA) Terastallization's 60 BP floor occurs after Technicia PARAMETRIZE { tera = GIMMICK_NONE; } PARAMETRIZE { tera = GIMMICK_TERA; } GIVEN { - ASSUME(gMovesInfo[MOVE_MEGA_DRAIN].power == 40); + ASSUME(GetMovePower(MOVE_MEGA_DRAIN) == 40); PLAYER(SPECIES_MR_MIME) { Ability(ABILITY_TECHNICIAN); TeraType(TYPE_GRASS); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -393,7 +393,7 @@ SINGLE_BATTLE_TEST("(TERA) Double Shock does not remove the user's Electric type { s16 damage[4]; GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE); PLAYER(SPECIES_PICHU) { TeraType(TYPE_ELECTRIC); } PLAYER(SPECIES_WOBBUFFET) OPPONENT(SPECIES_WOBBUFFET); @@ -608,8 +608,8 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the Stellar type boosts all moves { s16 damage[4]; GIVEN { - ASSUME(gMovesInfo[MOVE_MEGA_DRAIN].power == 40); - ASSUME(gMovesInfo[MOVE_BUBBLE].power == 40); + ASSUME(GetMovePower(MOVE_MEGA_DRAIN) == 40); + ASSUME(GetMovePower(MOVE_BUBBLE) == 40); PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -688,7 +688,7 @@ SINGLE_BATTLE_TEST("(TERA) Stellar type's one-time boost factors in dynamically- { s16 damage[4]; GIVEN { - ASSUME(gMovesInfo[MOVE_WEATHER_BALL].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_WEATHER_BALL) == TYPE_NORMAL); PLAYER(SPECIES_PELIPPER) { Ability(ABILITY_DRIZZLE); TeraType(TYPE_STELLAR); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -731,8 +731,8 @@ SINGLE_BATTLE_TEST("(TERA) Terapagos retains the Stellar type boost at all times PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_MACH_PUNCH; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_MACH_PUNCH].type != TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_MACH_PUNCH) != TYPE_NORMAL); PLAYER(SPECIES_TERAPAGOS); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/gimmick/zmove.c b/test/battle/gimmick/zmove.c index eb44184e5a..358e38d031 100644 --- a/test/battle/gimmick/zmove.c +++ b/test/battle/gimmick/zmove.c @@ -6,7 +6,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves do not retain priority") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_QUICK_ATTACK) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves do not retain priority") SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are not affected by -ate abilities") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); ASSUME(gSpeciesInfo[SPECIES_SWELLOW].types[1] == TYPE_FLYING); PLAYER(SPECIES_AURORUS) { Ability(ABILITY_REFRIGERATE); Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_SWELLOW); @@ -38,8 +38,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are not affected by -ate abilities") SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are affected by Ion Deluge") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_SWELLOW); } WHEN { @@ -57,8 +57,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves deal 1/4 damage through protect", s16 damag PARAMETRIZE { protected = TRUE; } PARAMETRIZE { protected = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); + ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -77,7 +77,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves deal 1/4 damage through protect", s16 damag SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESET_STATS clears a battler's negative stat stages") { GIVEN { - ASSUME(gMovesInfo[MOVE_LEECH_SEED].zMove.effect == Z_EFFECT_RESET_STATS); + ASSUME(GetMoveZEffect(MOVE_LEECH_SEED) == Z_EFFECT_RESET_STATS); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESET_STATS clears a battler's negative st SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_ALL_STATS_UP raises all of a battler's stat stages by one") { GIVEN { - ASSUME(gMovesInfo[MOVE_CELEBRATE].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_CELEBRATE].zMove.effect == Z_EFFECT_ALL_STATS_UP_1); + ASSUME(GetMoveType(MOVE_CELEBRATE) == TYPE_NORMAL); + ASSUME(GetMoveZEffect(MOVE_CELEBRATE) == Z_EFFECT_ALL_STATS_UP_1); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -118,8 +118,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_BOOST_CRITS raises a battler's critical hi { PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); GIVEN { - ASSUME(gMovesInfo[MOVE_FORESIGHT].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_FORESIGHT].zMove.effect == Z_EFFECT_BOOST_CRITS); + ASSUME(GetMoveType(MOVE_FORESIGHT) == TYPE_NORMAL); + ASSUME(GetMoveZEffect(MOVE_FORESIGHT) == Z_EFFECT_BOOST_CRITS); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -136,8 +136,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_BOOST_CRITS raises a battler's critical hi DOUBLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_FOLLOW_ME redirects attacks to the user") { GIVEN { - ASSUME(gMovesInfo[MOVE_DESTINY_BOND].type == TYPE_GHOST); - ASSUME(gMovesInfo[MOVE_DESTINY_BOND].zMove.effect == Z_EFFECT_FOLLOW_ME); + ASSUME(GetMoveType(MOVE_DESTINY_BOND) == TYPE_GHOST); + ASSUME(GetMoveZEffect(MOVE_DESTINY_BOND) == Z_EFFECT_FOLLOW_ME); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GHOSTIUM_Z); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -157,8 +157,8 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_FOLLOW_ME redirects attacks to the user") SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESTORE_REPLACEMENT_HP fully heals the replacement battler's HP") { GIVEN { - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].type == TYPE_DARK); - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].zMove.effect == Z_EFFECT_RESTORE_REPLACEMENT_HP); + ASSUME(GetMoveType(MOVE_PARTING_SHOT) == TYPE_DARK); + ASSUME(GetMoveZEffect(MOVE_PARTING_SHOT) == Z_EFFECT_RESTORE_REPLACEMENT_HP); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_DARKINIUM_Z); } PLAYER(SPECIES_WYNAUT) { HP(1); } OPPONENT(SPECIES_WOBBUFFET); @@ -181,11 +181,11 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_CURSE activates Z_EFFECT_RECOVER_HP or Z_E PARAMETRIZE { species = SPECIES_WOBBUFFET; } PARAMETRIZE { species = SPECIES_DUSCLOPS; } GIVEN { - ASSUME(gMovesInfo[MOVE_CURSE].type == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_CURSE) == TYPE_GHOST); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_GHOST); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_GHOST); ASSUME(gSpeciesInfo[SPECIES_DUSCLOPS].types[0] == TYPE_GHOST); - ASSUME(gMovesInfo[MOVE_CURSE].zMove.effect == Z_EFFECT_CURSE); + ASSUME(GetMoveZEffect(MOVE_CURSE) == Z_EFFECT_CURSE); PLAYER(species) { Item(ITEM_GHOSTIUM_Z); HP(1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -218,8 +218,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_CURSE activates Z_EFFECT_RECOVER_HP or Z_E SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used non-status move as a Z-Move") { GIVEN { - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING); - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].zMove.effect == Z_EFFECT_ATK_UP_2); + ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING); + ASSUME(GetMoveZEffect(MOVE_MIRROR_MOVE) == Z_EFFECT_ATK_UP_2); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -240,8 +240,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stage SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used status move regularly") { GIVEN { - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING); - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].zMove.effect == Z_EFFECT_ATK_UP_2); + ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING); + ASSUME(GetMoveZEffect(MOVE_MIRROR_MOVE) == Z_EFFECT_ATK_UP_2); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -259,8 +259,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stage SINGLE_BATTLE_TEST("(Z-MOVE) Z-Copycat raises the user's accuracy by one stage and copies the last used non-status move as a Z-Move") { GIVEN { - ASSUME(gMovesInfo[MOVE_COPYCAT].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_COPYCAT].zMove.effect == Z_EFFECT_ACC_UP_1); + ASSUME(GetMoveType(MOVE_COPYCAT) == TYPE_NORMAL); + ASSUME(GetMoveZEffect(MOVE_COPYCAT) == Z_EFFECT_ACC_UP_1); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -281,8 +281,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Me First raises the user's speed by two stages an PARAMETRIZE { meFirst = TRUE; } PARAMETRIZE { meFirst = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_ME_FIRST].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_ME_FIRST].zMove.effect == Z_EFFECT_SPD_UP_2); + ASSUME(GetMoveType(MOVE_ME_FIRST) == TYPE_NORMAL); + ASSUME(GetMoveZEffect(MOVE_ME_FIRST) == Z_EFFECT_SPD_UP_2); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -313,7 +313,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Nature Power transforms into different Z-Moves ba PARAMETRIZE { terrainMove = MOVE_GRASSY_TERRAIN; zMove = gTypesInfo[TYPE_GRASS].zMove; } PARAMETRIZE { terrainMove = MOVE_MISTY_TERRAIN; zMove = gTypesInfo[TYPE_FAIRY].zMove; } GIVEN { - ASSUME(gMovesInfo[MOVE_NATURE_POWER].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_NATURE_POWER) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -334,7 +334,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Hidden Power always transforms into Breakneck Bli PARAMETRIZE { iv = 21; } PARAMETRIZE { iv = 31; } GIVEN { - ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_HIDDEN_POWER) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); AttackIV(iv); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -354,7 +354,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Weather Ball transforms into different Z-Moves ba PARAMETRIZE { weatherMove = MOVE_SANDSTORM; zMove = gTypesInfo[TYPE_ROCK].zMove; } PARAMETRIZE { weatherMove = MOVE_HAIL; zMove = gTypesInfo[TYPE_ICE].zMove; } GIVEN { - ASSUME(gMovesInfo[MOVE_WEATHER_BALL].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_WEATHER_BALL) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -370,7 +370,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Weather Ball transforms into different Z-Moves ba SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk transforms a used non-status move into a Z-Move") { GIVEN { - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_SLEEP_TALK) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_ABSORB); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -385,7 +385,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk transforms a used non-status move into SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk turns Weather Ball into Breakneck Blitz even under rain") { GIVEN { - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_SLEEP_TALK) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_WEATHER_BALL); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -400,7 +400,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk turns Weather Ball into Breakneck Blit SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves and deals 25% of maximum HP to the user") { GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FIRIUM_Z); } OPPONENT(SPECIES_VIVILLON); } WHEN { @@ -417,8 +417,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves and deals 25% of ma DOUBLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves (from Z-Mirror Move)") { GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -436,8 +436,8 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves (from Z-Mirror Move SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves but not boosts granted") { GIVEN { - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].zMove.effect == Z_EFFECT_ATK_UP_1); + ASSUME(GetMoveType(MOVE_WILL_O_WISP) == TYPE_FIRE); + ASSUME(GetMoveZEffect(MOVE_WILL_O_WISP) == Z_EFFECT_ATK_UP_1); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FIRIUM_Z); } OPPONENT(SPECIES_VIVILLON); } WHEN { @@ -455,7 +455,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves but not boosts gran DOUBLE_BATTLE_TEST("(Z-MOVE) Instruct fails if the target last used a Z-Move") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -474,7 +474,7 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Instruct fails if the target last used a Z-Move") DOUBLE_BATTLE_TEST("(Z-MOVE) Dancer does not use a Z-Move if the battler has used a Z-Move the same turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Item(ITEM_NORMALIUM_Z); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -498,7 +498,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Light That Burns the Sky uses the battler's highest PARAMETRIZE { useSwordsDance = FALSE; } PARAMETRIZE { useSwordsDance = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); } OPPONENT(SPECIES_WOBBUFFET) { HP(1000); MaxHP(1000); }; // hits hard lol } WHEN { @@ -521,7 +521,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) 10,000,000 Volt Thunderbolt has an increased critic PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_6); - ASSUME(gMovesInfo[MOVE_10_000_000_VOLT_THUNDERBOLT].criticalHitStage == 2); + ASSUME(GetMoveCriticalHitStage(MOVE_10_000_000_VOLT_THUNDERBOLT) == 2); PLAYER(SPECIES_PIKACHU_PARTNER) { Item(ITEM_PIKASHUNIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -536,7 +536,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) 10,000,000 Volt Thunderbolt has an increased critic SINGLE_BATTLE_TEST("(Z-MOVE) Stoked Sparksurfer paralyzes the target") { GIVEN { - ASSUME(gMovesInfo[MOVE_STOKED_SPARKSURFER].additionalEffects[0].moveEffect == MOVE_EFFECT_PARALYSIS); + ASSUME(GetMoveAdditionalEffectById(MOVE_STOKED_SPARKSURFER, 0)->moveEffect == MOVE_EFFECT_PARALYSIS); PLAYER(SPECIES_RAICHU_ALOLA) { Item(ITEM_ALORAICHIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -551,7 +551,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Stoked Sparksurfer paralyzes the target") SINGLE_BATTLE_TEST("(Z-MOVE) Extreme Evoboost boosts all the user's stats by two stages") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXTREME_EVOBOOST].effect == EFFECT_EXTREME_EVOBOOST); + ASSUME(GetMoveEffect(MOVE_EXTREME_EVOBOOST) == EFFECT_EXTREME_EVOBOOST); PLAYER(SPECIES_EEVEE) { Item(ITEM_EEVIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -571,7 +571,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Extreme Evoboost boosts all the user's stats by two SINGLE_BATTLE_TEST("(Z-MOVE) Genesis Supernova sets up psychic terrain") { GIVEN { - ASSUME(gMovesInfo[MOVE_GENESIS_SUPERNOVA].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); + ASSUME(GetMoveEffect(MOVE_GENESIS_SUPERNOVA) == EFFECT_HIT_SET_REMOVE_TERRAIN); PLAYER(SPECIES_MEW) { Item(ITEM_MEWNIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -588,7 +588,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Genesis Supernova sets up psychic terrain") SINGLE_BATTLE_TEST("(Z-MOVE) Splintered Stormshards removes terrain") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPLINTERED_STORMSHARDS].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); + ASSUME(GetMoveEffect(MOVE_SPLINTERED_STORMSHARDS) == EFFECT_HIT_SET_REMOVE_TERRAIN); PLAYER(SPECIES_LYCANROC_DUSK) { Item(ITEM_LYCANIUM_Z); } OPPONENT(SPECIES_TAPU_LELE) { Ability(ABILITY_PSYCHIC_SURGE); HP(1000); MaxHP(1000); } } WHEN { @@ -606,7 +606,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Splintered Stormshards removes terrain") SINGLE_BATTLE_TEST("(Z-MOVE) Clangorous Soulblaze boosts all the user's stats by one stage") { GIVEN { - ASSUME(gMovesInfo[MOVE_CLANGOROUS_SOULBLAZE].additionalEffects[0].moveEffect == MOVE_EFFECT_ALL_STATS_UP); + ASSUME(GetMoveAdditionalEffectById(MOVE_CLANGOROUS_SOULBLAZE, 0)->moveEffect == MOVE_EFFECT_ALL_STATS_UP); PLAYER(SPECIES_KOMMO_O) { Item(ITEM_KOMMONIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -626,7 +626,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Clangorous Soulblaze boosts all the user's stats by SINGLE_BATTLE_TEST("(Z-MOVE) Guardian of Alola deals 75\% of the target's current HP") { GIVEN { - ASSUME(gMovesInfo[MOVE_GUARDIAN_OF_ALOLA].effect == EFFECT_GUARDIAN_OF_ALOLA); + ASSUME(GetMoveEffect(MOVE_GUARDIAN_OF_ALOLA) == EFFECT_GUARDIAN_OF_ALOLA); PLAYER(SPECIES_TAPU_FINI) { Item(ITEM_TAPUNIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -662,7 +662,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Revelation Dance always transforms into Breakneck PARAMETRIZE { species = SPECIES_ORICORIO_POM_POM; } PARAMETRIZE { species = SPECIES_ORICORIO_SENSU; } GIVEN { - ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_REVELATION_DANCE) == TYPE_NORMAL); PLAYER(species) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/air_balloon.c b/test/battle/hold_effect/air_balloon.c index 293e1d80ca..302a0e6397 100644 --- a/test/battle/hold_effect/air_balloon.c +++ b/test/battle/hold_effect/air_balloon.c @@ -4,9 +4,9 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND); - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_GROUND); - ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE); + ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_GROUND); + ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE); } SINGLE_BATTLE_TEST("Air Balloon prevents the holder from taking damage from ground type moves") diff --git a/test/battle/hold_effect/attack_up.c b/test/battle/hold_effect/attack_up.c index 383e564ce6..63203e588a 100644 --- a/test/battle/hold_effect/attack_up.c +++ b/test/battle/hold_effect/attack_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Liechi Berry raises the holder's Attack by one stage when HP drops to 1/4 or below") diff --git a/test/battle/hold_effect/berserk_gene.c b/test/battle/hold_effect/berserk_gene.c index 59f78c1a12..1ff601fc83 100644 --- a/test/battle/hold_effect/berserk_gene.c +++ b/test/battle/hold_effect/berserk_gene.c @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Berserk Gene sharply raises attack at the start of a single PARAMETRIZE { item = ITEM_NONE; } PARAMETRIZE { item = ITEM_BERSERK_GENE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene sharply raises attack at the start of a double PARAMETRIZE { item = ITEM_NONE; } PARAMETRIZE { item = ITEM_BERSERK_GENE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WOBBUFFET) { Item(item); } OPPONENT(SPECIES_WOBBUFFET); @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Berserk Gene activates on switch in", s16 damage) PARAMETRIZE { item = ITEM_NONE; } PARAMETRIZE { item = ITEM_BERSERK_GENE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WOBBUFFET) { Item(item); } OPPONENT(SPECIES_WOBBUFFET); @@ -91,7 +91,7 @@ SINGLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s PARAMETRIZE { item = ITEM_NONE; } PARAMETRIZE { item = ITEM_BERSERK_GENE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_OWN_TEMPO); Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -122,7 +122,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s PARAMETRIZE { item = ITEM_BERSERK_GENE; positionLeft = TRUE; } PARAMETRIZE { item = ITEM_BERSERK_GENE; positionLeft = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); if (positionLeft) { PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_OWN_TEMPO); Item(item); } PLAYER(SPECIES_WOBBUFFET); @@ -156,7 +156,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s SINGLE_BATTLE_TEST("Berserk Gene does not confuse on Misty Terrain but still raises attack sharply") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_TAPU_FINI) { Ability(ABILITY_MISTY_SURGE); Item(ITEM_BERSERK_GENE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/blunder_policy.c b/test/battle/hold_effect/blunder_policy.c index 552ad2f6fb..e9215b3eb2 100644 --- a/test/battle/hold_effect/blunder_policy.c +++ b/test/battle/hold_effect/blunder_policy.c @@ -10,7 +10,7 @@ SINGLE_BATTLE_TEST("Blunder Policy raises the users speed by 2 stages if the use { PASSES_RANDOMLY(3, 10, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -29,7 +29,7 @@ SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to a { PASSES_RANDOMLY(10, 10, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } OPPONENT(SPECIES_GASTLY); } WHEN { @@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to P { PASSES_RANDOMLY(10, 10, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/booster_energy.c b/test/battle/hold_effect/booster_energy.c index 072eb8df60..f6f44a272c 100644 --- a/test/battle/hold_effect/booster_energy.c +++ b/test/battle/hold_effect/booster_energy.c @@ -143,7 +143,7 @@ SINGLE_BATTLE_TEST("Booster Energy increases special attack by 30% if it is the PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; } GIVEN { - ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL); PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(110); SpDefense(100); Ability(ability); Item(item); } OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; } WHEN { @@ -169,7 +169,7 @@ SINGLE_BATTLE_TEST("Booster Energy increases special defense by 30% if it is the PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; } GIVEN { - ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL); PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(100); SpDefense(110); Ability(ability); Item(item); } OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; } WHEN { diff --git a/test/battle/hold_effect/clear_amulet.c b/test/battle/hold_effect/clear_amulet.c index d0666ff3a9..cc143c51e1 100644 --- a/test/battle/hold_effect/clear_amulet.c +++ b/test/battle/hold_effect/clear_amulet.c @@ -42,13 +42,13 @@ SINGLE_BATTLE_TEST("Clear Amulet prevents stat reducing effects") PARAMETRIZE { move = MOVE_SAND_ATTACK; } GIVEN { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2); - ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2); - ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2); + ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN)); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_CLEAR_AMULET); }; } WHEN { diff --git a/test/battle/hold_effect/covert_cloak.c b/test/battle/hold_effect/covert_cloak.c index b55b1492da..150ddcbba3 100644 --- a/test/battle/hold_effect/covert_cloak.c +++ b/test/battle/hold_effect/covert_cloak.c @@ -127,7 +127,6 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary DOUBLE_BATTLE_TEST("Covert Cloak does or does not block Sparkling Aria depending on number of targets hit") { u32 moveToUse; - KNOWN_FAILING; PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; } PARAMETRIZE { moveToUse = MOVE_TACKLE; } GIVEN { @@ -153,7 +152,6 @@ DOUBLE_BATTLE_TEST("Covert Cloak does or does not block Sparkling Aria depending SINGLE_BATTLE_TEST("Covert Cloak blocks Sparkling Aria in singles") { - KNOWN_FAILING; GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); Status1(STATUS1_BURN); } diff --git a/test/battle/hold_effect/critical_hit_up.c b/test/battle/hold_effect/critical_hit_up.c index c23f29773a..ee4cb6a7d2 100644 --- a/test/battle/hold_effect/critical_hit_up.c +++ b/test/battle/hold_effect/critical_hit_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_LANSAT_BERRY].holdEffect == HOLD_EFFECT_CRITICAL_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Lansat Berry raises the holder's critical-hit-ratio by two stages when HP drops to 1/4 or below") @@ -52,7 +52,7 @@ SINGLE_BATTLE_TEST("Lansat Berry raises the holder's critical-hit-ratio by two s { PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0); + ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0); ASSUME(B_CRIT_CHANCE >= GEN_6); PLAYER(SPECIES_WOBBUFFET) { MaxHP(160); HP(80); Item(ITEM_LANSAT_BERRY); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/hold_effect/defense_up.c b/test/battle/hold_effect/defense_up.c index 46130b9fe7..1812b96d33 100644 --- a/test/battle/hold_effect/defense_up.c +++ b/test/battle/hold_effect/defense_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_GANLON_BERRY].holdEffect == HOLD_EFFECT_DEFENSE_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Ganlon Berry raises the holder's Defense by one stage when HP drops to 1/4 or below") diff --git a/test/battle/hold_effect/eject_pack.c b/test/battle/hold_effect/eject_pack.c index 9272a23a7c..0d2696392f 100644 --- a/test/battle/hold_effect/eject_pack.c +++ b/test/battle/hold_effect/eject_pack.c @@ -76,12 +76,29 @@ SINGLE_BATTLE_TEST("Eject Pack will miss timing to switch out user if Emergency } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + } ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT); } THEN { EXPECT(player->species == SPECIES_WOBBUFFET); - EXPECT(player->item == ITEM_NONE); EXPECT(opponent->species == SPECIES_WYNAUT); } } + +SINGLE_BATTLE_TEST("Eject Pack activates once intimidate mon switches in") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { SWITCH(opponent, 1); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + } +} diff --git a/test/battle/hold_effect/jaboca_berry.c b/test/battle/hold_effect/jaboca_berry.c index 373780be71..756b5adf3c 100644 --- a/test/battle/hold_effect/jaboca_berry.c +++ b/test/battle/hold_effect/jaboca_berry.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_JABOCA_BERRY].holdEffect == HOLD_EFFECT_JABOCA_BERRY); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Jaboca Berry causes the attacker to lose 1/8 of its max HP if a physical move was used") @@ -16,7 +16,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry causes the attacker to lose 1/8 of its max HP i PARAMETRIZE { move = MOVE_TACKLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_JABOCA_BERRY); } } WHEN { @@ -44,7 +44,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry tirggers before Bug Bite can steal it") { KNOWN_FAILING; GIVEN { - ASSUME(gMovesInfo[MOVE_BUG_BITE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_BUG_BITE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_JABOCA_BERRY); } } WHEN { diff --git a/test/battle/hold_effect/kee_berry.c b/test/battle/hold_effect/kee_berry.c index 26cd2152a1..33de8ee004 100644 --- a/test/battle/hold_effect/kee_berry.c +++ b/test/battle/hold_effect/kee_berry.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_KEE_BERRY].holdEffect == HOLD_EFFECT_KEE_BERRY); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Kee Berry raises the holder's Defense by one stage when hit by a physical move") @@ -15,7 +15,7 @@ SINGLE_BATTLE_TEST("Kee Berry raises the holder's Defense by one stage when hit PARAMETRIZE { move = MOVE_TACKLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_KEE_BERRY); } } WHEN { diff --git a/test/battle/hold_effect/maranga_berry.c b/test/battle/hold_effect/maranga_berry.c index 77cdaddf42..eeb1aacf94 100644 --- a/test/battle/hold_effect/maranga_berry.c +++ b/test/battle/hold_effect/maranga_berry.c @@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by one stage when PARAMETRIZE { move = MOVE_TACKLE; } PARAMETRIZE { move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_MARANGA_BERRY); } } WHEN { @@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by one stage when SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by two stages with Ripen when hit by a special move") { GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_APPLIN) { Item(ITEM_MARANGA_BERRY); Ability(ABILITY_RIPEN); } } WHEN { diff --git a/test/battle/hold_effect/metronome.c b/test/battle/hold_effect/metronome.c index 21ad326cf1..f1d756b3a7 100644 --- a/test/battle/hold_effect/metronome.c +++ b/test/battle/hold_effect/metronome.c @@ -112,7 +112,7 @@ SINGLE_BATTLE_TEST("Metronome Item counts charging turn of moves for its attacki PARAMETRIZE {item = ITEM_NONE; } PARAMETRIZE {item = ITEM_METRONOME; } GIVEN { - ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].effect == EFFECT_SOLAR_BEAM); + ASSUME(GetMoveEffect(MOVE_SOLAR_BEAM) == EFFECT_SOLAR_BEAM); PLAYER(SPECIES_WOBBUFFET) { Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -134,7 +134,7 @@ SINGLE_BATTLE_TEST("Metronome Item doesn't increase damage per hit of multi-hit { s16 damage[3]; GIVEN { - ASSUME(gMovesInfo[MOVE_FURY_ATTACK].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_FURY_ATTACK) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_METRONOME); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/micle_berry.c b/test/battle/hold_effect/micle_berry.c index 87f6742609..818eae09a6 100644 --- a/test/battle/hold_effect/micle_berry.c +++ b/test/battle/hold_effect/micle_berry.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_MICLE_BERRY].holdEffect == HOLD_EFFECT_MICLE_BERRY); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2 when HP drops to 1/4 or below") @@ -52,7 +52,7 @@ SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2") { PASSES_RANDOMLY(24, 25, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_SUBMISSION].accuracy == 80); + ASSUME(GetMoveAccuracy(MOVE_SUBMISSION) == 80); PLAYER(SPECIES_WOBBUFFET) { MaxHP(160); HP(80); Item(ITEM_MICLE_BERRY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2") SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move across turns") { GIVEN { - ASSUME(gMovesInfo[MOVE_ROCK_SLIDE].accuracy == 90); + ASSUME(GetMoveAccuracy(MOVE_ROCK_SLIDE) == 90); PASSES_RANDOMLY(100, 100, RNG_ACCURACY); PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(26); Item(ITEM_MICLE_BERRY); } OPPONENT(SPECIES_WOBBUFFET); @@ -85,7 +85,7 @@ SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move acr SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move the same turn the berry was triggered") { GIVEN { - ASSUME(gMovesInfo[MOVE_ROCK_SLIDE].accuracy == 90); + ASSUME(GetMoveAccuracy(MOVE_ROCK_SLIDE) == 90); PASSES_RANDOMLY(100, 100, RNG_ACCURACY); PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(26); Item(ITEM_MICLE_BERRY); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/hold_effect/mirror_herb.c b/test/battle/hold_effect/mirror_herb.c index 88a7467334..68294bee43 100644 --- a/test/battle/hold_effect/mirror_herb.c +++ b/test/battle/hold_effect/mirror_herb.c @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Mirror Herb copies all of foe's positive stat changes in a t PARAMETRIZE { item = ITEM_NONE; } PARAMETRIZE { item = ITEM_MIRROR_HERB; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); Item(item); } } WHEN { diff --git a/test/battle/hold_effect/ogerpon_mask.c b/test/battle/hold_effect/ogerpon_mask.c index 209b854d66..919151684a 100644 --- a/test/battle/hold_effect/ogerpon_mask.c +++ b/test/battle/hold_effect/ogerpon_mask.c @@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Ogerpon Masks increase the base power of moves by 20%", s16 PARAMETRIZE { species = SPECIES_OGERPON_CORNERSTONE; item = ITEM_HEARTHFLAME_MASK; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); + ASSUME(GetMovePower(MOVE_TACKLE) > 0); PLAYER(species) { Item(item); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/protective_pads.c b/test/battle/hold_effect/protective_pads.c index 95de944b81..843d2fa003 100644 --- a/test/battle/hold_effect/protective_pads.c +++ b/test/battle/hold_effect/protective_pads.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_PROTECTIVE_PADS].holdEffect == HOLD_EFFECT_PROTECTIVE_PADS); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE); + ASSUME(MoveMakesContact(MOVE_TACKLE) == TRUE); } SINGLE_BATTLE_TEST("Protective Pads protected moves still make direct contact", s16 damage) diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c index aa312797b2..7b14d8748d 100644 --- a/test/battle/hold_effect/red_card.c +++ b/test/battle/hold_effect/red_card.c @@ -383,7 +383,7 @@ SINGLE_BATTLE_TEST("Red Card does not activate if attacker's Sheer Force applied SINGLE_BATTLE_TEST("Red Card is consumed after dragged out replacement has its Speed lowered by Sticky Web") { GIVEN { - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT) { Moves(MOVE_TACKLE); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } diff --git a/test/battle/hold_effect/restore_hp.c b/test/battle/hold_effect/restore_hp.c index 47f409ff84..ef96ead7e4 100644 --- a/test/battle/hold_effect/restore_hp.c +++ b/test/battle/hold_effect/restore_hp.c @@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Restore HP Item effects do not miss timing after a recoil mo PARAMETRIZE { item = ITEM_SITRUS_BERRY; } GIVEN { - ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil == 25); + ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) == 25); ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP); ASSUME(gItemsInfo[ITEM_BERRY_JUICE].holdEffect == HOLD_EFFECT_RESTORE_HP); ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP); diff --git a/test/battle/hold_effect/restore_stats.c b/test/battle/hold_effect/restore_stats.c index c0f888469c..192ad2f65e 100644 --- a/test/battle/hold_effect/restore_stats.c +++ b/test/battle/hold_effect/restore_stats.c @@ -9,7 +9,7 @@ ASSUMPTIONS SINGLE_BATTLE_TEST("White Herb restores stats when they're lowered") { GIVEN { - ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -103,7 +103,7 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move PARAMETRIZE { species = SPECIES_DUGTRIO_ALOLA; ability = ABILITY_TANGLING_HAIR; } GIVEN { - ASSUME(gMovesInfo[MOVE_DUAL_WINGBEAT].strikeCount == 2); + ASSUME(GetMoveStrikeCount(MOVE_DUAL_WINGBEAT) == 2); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } OPPONENT(species) { Ability(ability); } } WHEN { @@ -133,7 +133,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE); - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF); + ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF); PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/hold_effect/room_service.c b/test/battle/hold_effect/room_service.c index 04b6450e05..e775ca496c 100644 --- a/test/battle/hold_effect/room_service.c +++ b/test/battle/hold_effect/room_service.c @@ -9,9 +9,9 @@ ASSUMPTIONS SINGLE_BATTLE_TEST("Room Serive decreases the holder's seep by one stage") { GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM); - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); Item(ITEM_ROOM_SERVICE); } OPPONENT(SPECIES_WYNAUT) { HP(1); } diff --git a/test/battle/hold_effect/rowap_berry.c b/test/battle/hold_effect/rowap_berry.c index 5dc85492c3..2ad8b9d300 100644 --- a/test/battle/hold_effect/rowap_berry.c +++ b/test/battle/hold_effect/rowap_berry.c @@ -15,8 +15,8 @@ SINGLE_BATTLE_TEST("Rowap Berry causes the attacker to lose 1/8 of its max HP if PARAMETRIZE { move = MOVE_TACKLE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROWAP_BERRY); } } WHEN { @@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Rowap Berry causes the attacker to lose 1/8 of its max HP if SINGLE_BATTLE_TEST("Rowap Berry is not triggered by a physical move") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROWAP_BERRY); } } WHEN { diff --git a/test/battle/hold_effect/safety_goggles.c b/test/battle/hold_effect/safety_goggles.c index ec66ad8bcd..e2d329bcf6 100644 --- a/test/battle/hold_effect/safety_goggles.c +++ b/test/battle/hold_effect/safety_goggles.c @@ -9,7 +9,7 @@ ASSUMPTIONS SINGLE_BATTLE_TEST("Safety Goggles block powder and spore moves") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ABRA) { Item(ITEM_SAFETY_GOGGLES); } } WHEN { diff --git a/test/battle/hold_effect/seeds.c b/test/battle/hold_effect/seeds.c new file mode 100644 index 0000000000..10a415bd63 --- /dev/null +++ b/test/battle/hold_effect/seeds.c @@ -0,0 +1,62 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Electric Seed raises the holder's Defense on Electric Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Grassy Seed raises the holder's Defense on Grassy Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_GRASSY_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Misty Seed raises the holder's Sp. Defense on Misty Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_MISTY_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Psychic Seed raises the holder's Sp. Defense on Psychic Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!"); + } +} diff --git a/test/battle/hold_effect/special_attack_up.c b/test/battle/hold_effect/special_attack_up.c index ef348024fc..0199bab83c 100644 --- a/test/battle/hold_effect/special_attack_up.c +++ b/test/battle/hold_effect/special_attack_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_PETAYA_BERRY].holdEffect == HOLD_EFFECT_SP_ATTACK_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Petaya Berry raises the holder's Sp. Atk by one stage when HP drops to 1/4 or below") diff --git a/test/battle/hold_effect/special_defense_up.c b/test/battle/hold_effect/special_defense_up.c index 9585e5b5a7..e075d05c49 100644 --- a/test/battle/hold_effect/special_defense_up.c +++ b/test/battle/hold_effect/special_defense_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Apicot Berry raises the holder's Sp. Def by one stage when HP drops to 1/4 or below") diff --git a/test/battle/hold_effect/speed_up.c b/test/battle/hold_effect/speed_up.c index 4a8b28b6d9..f31ee7e924 100644 --- a/test/battle/hold_effect/speed_up.c +++ b/test/battle/hold_effect/speed_up.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_SALAC_BERRY].holdEffect == HOLD_EFFECT_SPEED_UP); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); } SINGLE_BATTLE_TEST("Salac Berry raises the holder's Speed by one stage when HP drops to 1/4 or below") diff --git a/test/battle/hold_effect/utility_umbrella.c b/test/battle/hold_effect/utility_umbrella.c index f04a773789..67a3be4c7a 100644 --- a/test/battle/hold_effect/utility_umbrella.c +++ b/test/battle/hold_effect/utility_umbrella.c @@ -5,8 +5,8 @@ ASSUMPTIONS { ASSUME(gItemsInfo[ITEM_UTILITY_UMBRELLA].holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); } SINGLE_BATTLE_TEST("Utility Umbrella blocks Sun damage modifiers", s16 damage) diff --git a/test/battle/item_effect/escape.c b/test/battle/item_effect/escape.c index bffa6e4292..dd27c425c2 100644 --- a/test/battle/item_effect/escape.c +++ b/test/battle/item_effect/escape.c @@ -21,7 +21,7 @@ WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle") WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle even if a move forbid them to") { GIVEN { - ASSUME(gMovesInfo[MOVE_MEAN_LOOK].effect == EFFECT_MEAN_LOOK); + ASSUME(GetMoveEffect(MOVE_MEAN_LOOK) == EFFECT_MEAN_LOOK); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/item_effect/increase_stat.c b/test/battle/item_effect/increase_stat.c index 9b3ced5759..2b9486e3a6 100644 --- a/test/battle/item_effect/increase_stat.c +++ b/test/battle/item_effect/increase_stat.c @@ -8,7 +8,7 @@ SINGLE_BATTLE_TEST("X Attack sharply raises battler's Attack stat", s16 damage) PARAMETRIZE { useItem = TRUE; } GIVEN { ASSUME(gItemsInfo[ITEM_X_ATTACK].battleUsage == EFFECT_ITEM_INCREASE_STAT); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("X Defense sharply raises battler's Defense stat", s16 damage PARAMETRIZE { useItem = TRUE; } GIVEN { ASSUME(gItemsInfo[ITEM_X_DEFENSE].battleUsage == EFFECT_ITEM_INCREASE_STAT); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("X Sp. Atk sharply raises battler's Sp. Attack stat", s16 dam PARAMETRIZE { useItem = TRUE; } GIVEN { ASSUME(gItemsInfo[ITEM_X_SP_ATK].battleUsage == EFFECT_ITEM_INCREASE_STAT); - ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_DISARMING_VOICE) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -80,7 +80,7 @@ SINGLE_BATTLE_TEST("X Sp. Def sharply raises battler's Sp. Defense stat", s16 da PARAMETRIZE { useItem = TRUE; } GIVEN { ASSUME(gItemsInfo[ITEM_X_SP_DEF].battleUsage == EFFECT_ITEM_INCREASE_STAT); - ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_DISARMING_VOICE) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -134,11 +134,11 @@ SINGLE_BATTLE_TEST("X Speed sharply raises battler's Speed stat", s16 damage) SINGLE_BATTLE_TEST("X Accuracy sharply raises battler's Accuracy stat") { - ASSUME(gMovesInfo[MOVE_SING].accuracy == 55); + ASSUME(GetMoveAccuracy(MOVE_SING) == 55); if (B_X_ITEMS_BUFF >= GEN_7) - PASSES_RANDOMLY(gMovesInfo[MOVE_SING].accuracy * 5 / 3, 100, RNG_ACCURACY); + PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SING) * 5 / 3, 100, RNG_ACCURACY); else - PASSES_RANDOMLY(gMovesInfo[MOVE_SING].accuracy * 4 / 3, 100, RNG_ACCURACY); + PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SING) * 4 / 3, 100, RNG_ACCURACY); GIVEN { ASSUME(gItemsInfo[ITEM_X_ACCURACY].battleUsage == EFFECT_ITEM_INCREASE_STAT); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/move.c b/test/battle/move.c index 9ee37391ec..ff397575b5 100644 --- a/test/battle/move.c +++ b/test/battle/move.c @@ -9,8 +9,8 @@ SINGLE_BATTLE_TEST("Accuracy controls the proportion of misses") PARAMETRIZE { move = MOVE_HYDRO_PUMP; } PARAMETRIZE { move = MOVE_RAZOR_LEAF; } PARAMETRIZE { move = MOVE_SCRATCH; } - ASSUME(0 < gMovesInfo[move].accuracy && gMovesInfo[move].accuracy <= 100); - PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100, RNG_ACCURACY); + ASSUME(0 < GetMoveAccuracy(move) && GetMoveAccuracy(move) <= 100); + PASSES_RANDOMLY(GetMoveAccuracy(move), 100, RNG_ACCURACY); GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("AdditionalEffect.chance controls the proportion of secondary SINGLE_BATTLE_TEST("Turn order is determined by priority") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority > gMovesInfo[MOVE_TACKLE].priority); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) > GetMovePriority(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -86,10 +86,10 @@ DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie PASSES_RANDOMLY(24, 24, RNG_SPEED_TIE); GIVEN { - ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR); - ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING); - ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_POWER_BASED_ON_TARGET_HP); - ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG); + ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR); + ASSUME(GetMoveEffect(MOVE_LIFE_DEW) == EFFECT_JUNGLE_HEALING); + ASSUME(GetMoveEffect(MOVE_CRUSH_GRIP) == EFFECT_POWER_BASED_ON_TARGET_HP); + ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_SUPER_FANG); PLAYER(SPECIES_WOBBUFFET) { MaxHP(480); HP(360); Defense(100); Speed(1); } PLAYER(SPECIES_WYNAUT) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Attack(100); Speed(1); } @@ -153,7 +153,7 @@ SINGLE_BATTLE_TEST("Slash's critical hits occur at a 1/8 rate") PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1); + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -188,7 +188,7 @@ SINGLE_BATTLE_TEST("Critical hits do not ignore positive stat stages", s16 damag PARAMETRIZE { move = MOVE_HOWL; } PARAMETRIZE { move = MOVE_TAIL_WHIP; } GIVEN { - ASSUME(gMovesInfo[MOVE_SCRATCH].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -209,7 +209,7 @@ SINGLE_BATTLE_TEST("Critical hits ignore negative stat stages", s16 damage) PARAMETRIZE { move = MOVE_HARDEN; } PARAMETRIZE { move = MOVE_GROWL; } GIVEN { - ASSUME(gMovesInfo[MOVE_SCRATCH].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -255,7 +255,7 @@ DOUBLE_BATTLE_TEST("Moves do not fail if an alive partner is the target") DOUBLE_BATTLE_TEST("Moves fail if they target into a pokemon that was fainted by the previous move") { GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { HP(1); } OPPONENT(SPECIES_WOBBUFFET) { HP(1); } @@ -278,7 +278,7 @@ DOUBLE_BATTLE_TEST("Moves fail if they target into a pokemon that was fainted by DOUBLE_BATTLE_TEST("Moves that target the field are not going to fail if one mon fainted by the previous move") { GIVEN { - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { HP(1); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/absorb.c b/test/battle/move_effect/absorb.c index 6ed1403fee..456c888cd4 100644 --- a/test/battle/move_effect/absorb.c +++ b/test/battle/move_effect/absorb.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ABSORB].effect == EFFECT_ABSORB); + ASSUME(GetMoveEffect(MOVE_ABSORB) == EFFECT_ABSORB); } SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt") @@ -24,25 +24,6 @@ SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt") } } -SINGLE_BATTLE_TEST("Absorb deals 50% of the damage dealt to user agains Liquid Ooze") -{ - s16 damage; - s16 healed; - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } - } WHEN { - TURN { MOVE(player, MOVE_ABSORB); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player); - HP_BAR(opponent, captureDamage: &damage); - HP_BAR(player, captureDamage: &healed); - MESSAGE("Wobbuffet sucked up the liquid ooze!"); - } THEN { - EXPECT_MUL_EQ(damage, Q_4_12(0.5), healed); - } -} - SINGLE_BATTLE_TEST("Absorb fails if Heal Block applies") { GIVEN { @@ -69,7 +50,7 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar s16 healedRight; GIVEN { - ASSUME(gMovesInfo[MOVE_MATCHA_GOTCHA].effect == EFFECT_ABSORB); + ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB); PLAYER(SPECIES_PIKACHU) { HP(1); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_STARYU); @@ -88,25 +69,6 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar } } -DOUBLE_BATTLE_TEST("Matcha Gatcha will faint the pokemon if Liquid Ooze drain deals enough damage") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_MATCHA_GOTCHA].effect == EFFECT_ABSORB); - PLAYER(SPECIES_WOBBUFFET) { HP(1); } - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft); - HP_BAR(opponentLeft); - HP_BAR(playerLeft); - MESSAGE("Wobbuffet sucked up the liquid ooze!"); - MESSAGE("Wobbuffet fainted!"); - } -} - SINGLE_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt") { s16 damage; diff --git a/test/battle/move_effect/accuracy_down.c b/test/battle/move_effect/accuracy_down.c index f174a7f946..c11001928f 100644 --- a/test/battle/move_effect/accuracy_down.c +++ b/test/battle/move_effect/accuracy_down.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); } SINGLE_BATTLE_TEST("Sand Attack lowers Accuracy by 1 stage") { - PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY); + PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SCRATCH) * 3 / 4, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100); + ASSUME(GetMoveAccuracy(MOVE_SCRATCH) == 100); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/acrobatics.c b/test/battle/move_effect/acrobatics.c index 70953d0958..809b77f948 100644 --- a/test/battle/move_effect/acrobatics.c +++ b/test/battle/move_effect/acrobatics.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ACROBATICS].effect == EFFECT_ACROBATICS); - ASSUME(gMovesInfo[MOVE_ACROBATICS].type == TYPE_FLYING); + ASSUME(GetMoveEffect(MOVE_ACROBATICS) == EFFECT_ACROBATICS); + ASSUME(GetMoveType(MOVE_ACROBATICS) == TYPE_FLYING); } SINGLE_BATTLE_TEST("Acrobatics doubles in power if the user has no held item", s16 damage) diff --git a/test/battle/move_effect/after_you.c b/test/battle/move_effect/after_you.c index c1202f0f9c..42eb0f3ff9 100644 --- a/test/battle/move_effect/after_you.c +++ b/test/battle/move_effect/after_you.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_AFTER_YOU].effect == EFFECT_AFTER_YOU); + ASSUME(GetMoveEffect(MOVE_AFTER_YOU) == EFFECT_AFTER_YOU); } DOUBLE_BATTLE_TEST("After You makes the target move after user") @@ -112,7 +112,7 @@ DOUBLE_BATTLE_TEST("After You doesn't fail if the turn order remains the same af DOUBLE_BATTLE_TEST("After You ignores the effects of Quash") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH); + ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WYNAUT) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } diff --git a/test/battle/move_effect/ally_switch.c b/test/battle/move_effect/ally_switch.c index 974730f120..7222f34587 100644 --- a/test/battle/move_effect/ally_switch.c +++ b/test/battle/move_effect/ally_switch.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ALLY_SWITCH].effect == EFFECT_ALLY_SWITCH); + ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH); } SINGLE_BATTLE_TEST("Ally Switch fails in a single battle") @@ -41,8 +41,8 @@ DOUBLE_BATTLE_TEST("Ally Switch fails if there is no partner") DOUBLE_BATTLE_TEST("Ally Switch changes the position of battlers") { GIVEN { - ASSUME(gMovesInfo[MOVE_SCREECH].effect == EFFECT_DEFENSE_DOWN_2); - ASSUME(gMovesInfo[MOVE_SCREECH].target == MOVE_TARGET_SELECTED); + ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2); + ASSUME(GetMoveTarget(MOVE_SCREECH) == MOVE_TARGET_SELECTED); PLAYER(SPECIES_WOBBUFFET) { Speed(5); } // Wobb is playerLeft, but it'll be Wynaut after Ally Switch PLAYER(SPECIES_WYNAUT) { Speed(4); } OPPONENT(SPECIES_KADABRA) { Speed(3); } @@ -72,7 +72,7 @@ DOUBLE_BATTLE_TEST("Ally Switch changes the position of battlers") DOUBLE_BATTLE_TEST("Ally Switch does not redirect the target of Snipe Shot") { GIVEN { - ASSUME(gMovesInfo[MOVE_SNIPE_SHOT].effect == EFFECT_SNIPE_SHOT); + ASSUME(GetMoveEffect(MOVE_SNIPE_SHOT) == EFFECT_SNIPE_SHOT); PLAYER(SPECIES_WOBBUFFET); // Wobb is playerLeft, but it'll be Wynaut after Ally Switch PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_KADABRA); @@ -207,7 +207,7 @@ DOUBLE_BATTLE_TEST("Ally switch swaps sky drop targets if being used by partner" { u8 visibility; GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP); + ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP); PLAYER(SPECIES_FEAROW) { Speed(100); } PLAYER(SPECIES_XATU) { Speed(150); } OPPONENT(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); } @@ -244,7 +244,7 @@ DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is be { u8 visibility; GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP); + ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP); PLAYER(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); } PLAYER(SPECIES_WYNAUT) { Speed(30); } OPPONENT(SPECIES_FEAROW) { Speed(100); } @@ -277,5 +277,25 @@ DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is be } } +// Test passes in isolation but fails on CI +/* +DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data") +{ + KNOWN_FAILING; // Test passes in isolation but fails on CI + GIVEN { + ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH); + PLAYER(SPECIES_HOOPA); + PLAYER(SPECIES_ZOROARK); + PLAYER(SPECIES_MAMOSWINE); // the third member here is required for zoroark + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); } + } THEN { + EXPECT(&gPlayerParty[2] == gBattleStruct->illusion[0].mon); + } +} +*/ + // Triple Battles required to test //TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle"); diff --git a/test/battle/move_effect/assist.c b/test/battle/move_effect/assist.c index 0c9a0b6128..6036de8e8c 100644 --- a/test/battle/move_effect/assist.c +++ b/test/battle/move_effect/assist.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ASSIST].effect == EFFECT_ASSIST); + ASSUME(GetMoveEffect(MOVE_ASSIST) == EFFECT_ASSIST); } TO_DO_BATTLE_TEST("Assist randomly calls a move from any party member"); diff --git a/test/battle/move_effect/attack_accuracy_up.c b/test/battle/move_effect/attack_accuracy_up.c index 102f4d4d21..25b09ab1c0 100644 --- a/test/battle/move_effect/attack_accuracy_up.c +++ b/test/battle/move_effect/attack_accuracy_up.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Hone Claws increases Attack and Accuracy by one stage each") { GIVEN { - ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP); + ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_down.c b/test/battle/move_effect/attack_down.c index e88ef43c26..eb562c0c6a 100644 --- a/test/battle/move_effect/attack_down.c +++ b/test/battle/move_effect/attack_down.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); } SINGLE_BATTLE_TEST("Growl lowers Attack by 1 stage", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Growl lowers Attack by 1 stage", s16 damage) PARAMETRIZE { lowerAttack = FALSE; } PARAMETRIZE { lowerAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_down_2.c b/test/battle/move_effect/attack_down_2.c index 6fefec5e45..896bbf947c 100644 --- a/test/battle/move_effect/attack_down_2.c +++ b/test/battle/move_effect/attack_down_2.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2); } SINGLE_BATTLE_TEST("Charm lowers Attack by 2 stages", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Charm lowers Attack by 2 stages", s16 damage) PARAMETRIZE { lowerAttack = FALSE; } PARAMETRIZE { lowerAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_spatk_up.c b/test/battle/move_effect/attack_spatk_up.c index b5aa2418a2..671ed667a6 100644 --- a/test/battle/move_effect/attack_spatk_up.c +++ b/test/battle/move_effect/attack_spatk_up.c @@ -4,7 +4,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WORK_UP].effect == EFFECT_ATTACK_SPATK_UP); + ASSUME(GetMoveEffect(MOVE_WORK_UP) == EFFECT_ATTACK_SPATK_UP); } SINGLE_BATTLE_TEST("Work Up raises Attack and Sp. Attack by 1 stage each", s16 damage) @@ -16,8 +16,8 @@ SINGLE_BATTLE_TEST("Work Up raises Attack and Sp. Attack by 1 stage each", s16 d PARAMETRIZE { raiseStats = FALSE; move = MOVE_SWIFT; } PARAMETRIZE { raiseStats = TRUE; move = MOVE_SWIFT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_up.c b/test/battle/move_effect/attack_up.c index da878fb60d..1865c7f30e 100644 --- a/test/battle/move_effect/attack_up.c +++ b/test/battle/move_effect/attack_up.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MEDITATE].effect == EFFECT_ATTACK_UP); + ASSUME(GetMoveEffect(MOVE_MEDITATE) == EFFECT_ATTACK_UP); } SINGLE_BATTLE_TEST("Meditate raises Attack by 1 stage", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Meditate raises Attack by 1 stage", s16 damage) PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_up_2.c b/test/battle/move_effect/attack_up_2.c index 1f44efe9e3..fd247fad01 100644 --- a/test/battle/move_effect/attack_up_2.c +++ b/test/battle/move_effect/attack_up_2.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); } SINGLE_BATTLE_TEST("Swords Dance raises Attack by 2 stages", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Swords Dance raises Attack by 2 stages", s16 damage) PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/attack_up_user_ally.c b/test/battle/move_effect/attack_up_user_ally.c index 1d623c2bbd..8f9c4a3388 100644 --- a/test/battle/move_effect/attack_up_user_ally.c +++ b/test/battle/move_effect/attack_up_user_ally.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); } SINGLE_BATTLE_TEST("Howl raises user's Attack by 1 stage", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Howl raises user's Attack by 1 stage", s16 damage) PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Howl raises user's and partner's Attack by 1 stage", s16 dam PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(15); } PLAYER(SPECIES_WYNAUT) { Speed(10); } OPPONENT(SPECIES_WOBBUFFET) { Speed(13); } @@ -69,7 +69,7 @@ DOUBLE_BATTLE_TEST("Howl does not work on partner if it has Soundproof") s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(15); } PLAYER(SPECIES_VOLTORB) { Speed(10); Ability(ABILITY_SOUNDPROOF); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); } diff --git a/test/battle/move_effect/aura_wheel.c b/test/battle/move_effect/aura_wheel.c index 3d601f3583..dfd31c878f 100644 --- a/test/battle/move_effect/aura_wheel.c +++ b/test/battle/move_effect/aura_wheel.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffectSelf(MOVE_AURA_WHEEL, MOVE_EFFECT_SPD_PLUS_1) == TRUE); - ASSUME(gMovesInfo[MOVE_AURA_WHEEL].effect == EFFECT_AURA_WHEEL); + ASSUME(GetMoveEffect(MOVE_AURA_WHEEL) == EFFECT_AURA_WHEEL); } SINGLE_BATTLE_TEST("Aura Wheel raises Speed; fails if the user is not Morpeko") diff --git a/test/battle/move_effect/aurora_veil.c b/test/battle/move_effect/aurora_veil.c index f681e965d7..b57c85df06 100644 --- a/test/battle/move_effect/aurora_veil.c +++ b/test/battle/move_effect/aurora_veil.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL); + ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL); } SINGLE_BATTLE_TEST("Aurora Veil can only be used in Hail and Snow") diff --git a/test/battle/move_effect/baton_pass.c b/test/battle/move_effect/baton_pass.c index b6a27179f3..cb6530ae89 100644 --- a/test/battle/move_effect/baton_pass.c +++ b/test/battle/move_effect/baton_pass.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); } // This softlocked the game before. @@ -39,9 +39,6 @@ TO_DO_BATTLE_TEST("Baton Pass doesn't pass ability changes"); // TO_DO_BATTLE_TEST("Baton Pass passes confusion status"); // test/battle/status2/confusion.c -TO_DO_BATTLE_TEST("Baton Pass passes Cursed status"); // test/battle/move_effect/curse.c -TO_DO_BATTLE_TEST("Baton Pass doesn't pass Disable's effect"); // test/battle/move_effect/disable.c -TO_DO_BATTLE_TEST("Baton Pass passes Dragon Cheer's effect"); // test/battle/move_effect/dragon_cheer.c TO_DO_BATTLE_TEST("Baton Pass passes Fairy lock's escape prevention effect"); // test/battle/move_effect/fairy_lock.c TO_DO_BATTLE_TEST("Baton Pass passes Focus Energy's effect"); // test/battle/move_effect/focus_energy.c TO_DO_BATTLE_TEST("Baton Pass passes Heal Block's effect"); // test/battle/move_effect/heal_block.c diff --git a/test/battle/move_effect/beak_blast.c b/test/battle/move_effect/beak_blast.c index e716b7717f..92557ddee3 100644 --- a/test/battle/move_effect/beak_blast.c +++ b/test/battle/move_effect/beak_blast.c @@ -3,13 +3,13 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BEAK_BLAST].effect == EFFECT_BEAK_BLAST); + ASSUME(GetMoveEffect(MOVE_BEAK_BLAST) == EFFECT_BEAK_BLAST); } DOUBLE_BATTLE_TEST("Beak Blast's charging message is shown before other moves are used") { GIVEN { - ASSUME(gMovesInfo[MOVE_BEAK_BLAST].priority < 0); + ASSUME(GetMovePriority(MOVE_BEAK_BLAST) < 0); PLAYER(SPECIES_WYNAUT) { Speed(10); } PLAYER(SPECIES_WOBBUFFET) { Speed(5); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } @@ -36,8 +36,8 @@ DOUBLE_BATTLE_TEST("Beak Blast's charging message is shown before other moves ar DOUBLE_BATTLE_TEST("Beak Blast burns all who make contact with the pokemon") { GIVEN { - ASSUME(gMovesInfo[MOVE_BEAK_BLAST].priority < 0); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMovePriority(MOVE_BEAK_BLAST) < 0); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_WYNAUT) { Speed(10); } PLAYER(SPECIES_WOBBUFFET) { Speed(5); } OPPONENT(SPECIES_WOBBUFFET) { Speed(3); } @@ -80,9 +80,9 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used") PARAMETRIZE { move = MOVE_LEER; burn = FALSE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(!gMovesInfo[MOVE_WATER_GUN].makesContact); - ASSUME(!gMovesInfo[MOVE_LEER].makesContact); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(!MoveMakesContact(MOVE_WATER_GUN)); + ASSUME(!MoveMakesContact(MOVE_LEER)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -113,4 +113,5 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used") } TO_DO_BATTLE_TEST("Beak Blast's charging message is shown regardless if it would've missed"); +TO_DO_BATTLE_TEST("Beak Blast fails if it's forced by Encore after choosing a different move"); TO_DO_BATTLE_TEST("Bulletproof is immune to Beak Blast but not to the burn it causes"); diff --git a/test/battle/move_effect/belch.c b/test/battle/move_effect/belch.c index 2a732e0e45..1abcefb353 100644 --- a/test/battle/move_effect/belch.c +++ b/test/battle/move_effect/belch.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BELCH].effect == EFFECT_BELCH); - ASSUME(gMovesInfo[MOVE_MUD_SHOT].type == TYPE_GROUND); + ASSUME(GetMoveEffect(MOVE_BELCH) == EFFECT_BELCH); + ASSUME(GetMoveType(MOVE_MUD_SHOT) == TYPE_GROUND); ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].holdEffect == HOLD_EFFECT_RESIST_BERRY); ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].holdEffectParam == TYPE_GROUND); ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].pocket == POCKET_BERRIES); @@ -21,7 +21,7 @@ AI_SINGLE_BATTLE_TEST("AI: Belch has nonzero score after eating a berry") TURN { MOVE(player, MOVE_MUD_SHOT); EXPECT_MOVE(opponent, MOVE_TACKLE); } TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_BELCH);} } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent); } } @@ -53,6 +53,64 @@ SINGLE_BATTLE_TEST("Belch cannot be used if the user has not eaten a berry") } } -TO_DO_BATTLE_TEST("Belch can still be used after switching out"); -TO_DO_BATTLE_TEST("Belch can still be used after fainting"); -TO_DO_BATTLE_TEST("Belch can still be used after restoring the consumed berry"); +SINGLE_BATTLE_TEST("Belch can still be used after switching out") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS); + PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); } + PLAYER(SPECIES_SKWOVET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STUFF_CHEEKS); } + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + TURN { MOVE(player, MOVE_BELCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player); + SWITCH_OUT_MESSAGE("Greedent"); + SWITCH_OUT_MESSAGE("Skwovet"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player); + } +} + +SINGLE_BATTLE_TEST("Belch can still be used after fainting") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS); + ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO); + ASSUME(GetMoveEffect(MOVE_REVIVAL_BLESSING) == EFFECT_REVIVAL_BLESSING); + PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); } + PLAYER(SPECIES_SKWOVET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STUFF_CHEEKS); MOVE(opponent, MOVE_FISSURE); SEND_OUT(player, 1); } + TURN { MOVE(player, MOVE_REVIVAL_BLESSING, partyIndex: 0); } + TURN { SWITCH(player, 0); } + TURN { MOVE(player, MOVE_BELCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVIVAL_BLESSING, player); + SWITCH_OUT_MESSAGE("Skwovet"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player); + } +} + +SINGLE_BATTLE_TEST("Belch can still be used after restoring the consumed berry") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS); + ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE); + PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); } + PLAYER(SPECIES_SKWOVET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STUFF_CHEEKS); } + TURN { MOVE(player, MOVE_RECYCLE); } + TURN { MOVE(player, MOVE_BELCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_RECYCLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player); + } +} diff --git a/test/battle/move_effect/belly_drum.c b/test/battle/move_effect/belly_drum.c index bfc558a982..e36689ac34 100644 --- a/test/battle/move_effect/belly_drum.c +++ b/test/battle/move_effect/belly_drum.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM); } SINGLE_BATTLE_TEST("Belly Drum cuts the user's HP in half") @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Belly Drum maximizes the user's Attack stat", s16 damage) PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Belly Drum fails if user's current HP is half or less than h SINGLE_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6") { GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Belly Drum minimizes the user's Attack stat with Contrary", PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_CONTRARY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/bide.c b/test/battle/move_effect/bide.c index f99829d57c..177b139d08 100644 --- a/test/battle/move_effect/bide.c +++ b/test/battle/move_effect/bide.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BIDE].effect == EFFECT_BIDE); + ASSUME(GetMoveEffect(MOVE_BIDE) == EFFECT_BIDE); } SINGLE_BATTLE_TEST("Bide deals twice the taken damage over two turns") diff --git a/test/battle/move_effect/body_press.c b/test/battle/move_effect/body_press.c index 3a61c4d55d..d3aafa2d32 100644 --- a/test/battle/move_effect/body_press.c +++ b/test/battle/move_effect/body_press.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BODY_PRESS].effect == EFFECT_BODY_PRESS); - ASSUME(gMovesInfo[MOVE_BODY_PRESS].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_BODY_PRESS) == EFFECT_BODY_PRESS); + ASSUME(GetMoveCategory(MOVE_BODY_PRESS) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Body Press uses physical defense stat of target", s16 damage) @@ -15,8 +15,8 @@ SINGLE_BATTLE_TEST("Body Press uses physical defense stat of target", s16 damage PARAMETRIZE { move = MOVE_BODY_PRESS; } GIVEN { - ASSUME(gMovesInfo[MOVE_DRILL_PECK].power == gMovesInfo[MOVE_BODY_PRESS].power); - ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); + ASSUME(GetMovePower(MOVE_DRILL_PECK) == GetMovePower(MOVE_BODY_PRESS)); + ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2); PLAYER(SPECIES_MEW); OPPONENT(SPECIES_SHELLDER); } WHEN { @@ -55,8 +55,8 @@ SINGLE_BATTLE_TEST("Body Press's damage depends on the user's Defense and not At PARAMETRIZE { move = MOVE_SWORDS_DANCE; } PARAMETRIZE { move = MOVE_CELEBRATE; } // Nothing, stats are default GIVEN { - ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2); - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Attack(150); Defense(150); } } WHEN { @@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Body Press uses Defense Stat even in Wonder Room", s16 damag PARAMETRIZE { move = MOVE_WONDER_ROOM; } PARAMETRIZE { move = MOVE_CELEBRATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_WONDER_ROOM].effect == EFFECT_WONDER_ROOM); + ASSUME(GetMoveEffect(MOVE_WONDER_ROOM) == EFFECT_WONDER_ROOM); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { SpDefense(50); Defense(150); } } WHEN { @@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Body Press uses Special Defense stat Stages in Wonder Room", PARAMETRIZE { move = MOVE_AMNESIA; } PARAMETRIZE { move = MOVE_CELEBRATE; } // Nothing, stats are default GIVEN { - ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2); - ASSUME(gMovesInfo[MOVE_AMNESIA].effect == EFFECT_SPECIAL_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_AMNESIA) == EFFECT_SPECIAL_DEFENSE_UP_2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { SpDefense(150); Defense(150); } } WHEN { diff --git a/test/battle/move_effect/brick_break.c b/test/battle/move_effect/brick_break.c index 513369b5a1..a4aae1e683 100644 --- a/test/battle/move_effect/brick_break.c +++ b/test/battle/move_effect/brick_break.c @@ -3,11 +3,11 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BRICK_BREAK].effect == EFFECT_BRICK_BREAK); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN); - ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT); - ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL); + ASSUME(GetMoveEffect(MOVE_BRICK_BREAK) == EFFECT_BRICK_BREAK); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN); + ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT); + ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL); } SINGLE_BATTLE_TEST("Brick Break removes Light Screen, Reflect and Aurora Veil from the target's side of the field") diff --git a/test/battle/move_effect/change_type_on_item.c b/test/battle/move_effect/change_type_on_item.c index 6365215a42..f5c8f92376 100644 --- a/test/battle/move_effect/change_type_on_item.c +++ b/test/battle/move_effect/change_type_on_item.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TECHNO_BLAST].effect == EFFECT_CHANGE_TYPE_ON_ITEM); - ASSUME(gMovesInfo[MOVE_TECHNO_BLAST].argument == HOLD_EFFECT_DRIVE); + ASSUME(GetMoveEffect(MOVE_TECHNO_BLAST) == EFFECT_CHANGE_TYPE_ON_ITEM); + ASSUME(GetMoveEffectArg_HoldEffect(MOVE_TECHNO_BLAST) == HOLD_EFFECT_DRIVE); } SINGLE_BATTLE_TEST("Techno Blast changes type depending on the drive the user holds") diff --git a/test/battle/move_effect/charge.c b/test/battle/move_effect/charge.c index b057fa4753..bd84a9b4e2 100644 --- a/test/battle/move_effect/charge.c +++ b/test/battle/move_effect/charge.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(!IS_MOVE_STATUS(MOVE_THUNDERBOLT)); - ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC); + ASSUME(!IsBattleMoveStatus(MOVE_THUNDERBOLT)); + ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); } SINGLE_BATTLE_TEST("Charge doubles the damage of the next Electric move of the user") @@ -88,7 +88,7 @@ SINGLE_BATTLE_TEST("Charge's effect does not stack with Electromorphosis or Wind PARAMETRIZE { species = SPECIES_TADBULB; ability = ABILITY_ELECTROMORPHOSIS; } GIVEN { - ASSUME(gMovesInfo[MOVE_AIR_CUTTER].windMove == TRUE); + ASSUME(IsWindMove(MOVE_AIR_CUTTER)); PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -114,8 +114,8 @@ SINGLE_BATTLE_TEST("Charge's effect is removed regardless if the next move is El s16 chargedUpDamage = 0; GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC); - ASSUME(!IS_MOVE_STATUS(MOVE_TACKLE)); + ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ELECTRIC); + ASSUME(!IsBattleMoveStatus(MOVE_TACKLE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/chilly_reception.c b/test/battle/move_effect/chilly_reception.c index 7e821abe3d..9b464f0d03 100644 --- a/test/battle/move_effect/chilly_reception.c +++ b/test/battle/move_effect/chilly_reception.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CHILLY_RECEPTION].effect == EFFECT_CHILLY_RECEPTION); + ASSUME(GetMoveEffect(MOVE_CHILLY_RECEPTION) == EFFECT_CHILLY_RECEPTION); } SINGLE_BATTLE_TEST("Chilly Reception sets up snow and switches the user out") diff --git a/test/battle/move_effect/coaching.c b/test/battle/move_effect/coaching.c index 451ac80495..0cfc593d35 100644 --- a/test/battle/move_effect/coaching.c +++ b/test/battle/move_effect/coaching.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_COACHING].effect == EFFECT_COACHING); + ASSUME(GetMoveEffect(MOVE_COACHING) == EFFECT_COACHING); } DOUBLE_BATTLE_TEST("Coaching raises Attack and Defense of ally by 1 stage each") @@ -25,7 +25,7 @@ DOUBLE_BATTLE_TEST("Coaching raises Attack and Defense of ally by 1 stage each") DOUBLE_BATTLE_TEST("Coaching bypasses Protect") { GIVEN { - ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -42,7 +42,7 @@ DOUBLE_BATTLE_TEST("Coaching bypasses Protect") DOUBLE_BATTLE_TEST("Coaching bypasses Crafty Shield") { GIVEN { - ASSUME(gMovesInfo[MOVE_CRAFTY_SHIELD].effect == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_CRAFTY_SHIELD) == EFFECT_PROTECT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -60,7 +60,7 @@ DOUBLE_BATTLE_TEST("Coaching fails if all allies are is semi-invulnerable") { KNOWN_FAILING; // Coaching succeeds GIVEN { - ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_HAWLUCHA); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/collision_course.c b/test/battle/move_effect/collision_course.c index 9eeeda5b1e..9933df0dc7 100644 --- a/test/battle/move_effect/collision_course.c +++ b/test/battle/move_effect/collision_course.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_COLLISION_COURSE].effect == EFFECT_COLLISION_COURSE); + ASSUME(GetMoveEffect(MOVE_COLLISION_COURSE) == EFFECT_COLLISION_COURSE); } SINGLE_BATTLE_TEST("Collision Course damage is increased by 33 Percent if super effective", s16 damage) diff --git a/test/battle/move_effect/confuse.c b/test/battle/move_effect/confuse.c index 0533821972..425adfc889 100644 --- a/test/battle/move_effect/confuse.c +++ b/test/battle/move_effect/confuse.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TEETER_DANCE].effect == EFFECT_CONFUSE); + ASSUME(GetMoveEffect(MOVE_TEETER_DANCE) == EFFECT_CONFUSE); } SINGLE_BATTLE_TEST("Teeter Dance confuses target") diff --git a/test/battle/move_effect/corrosive_gas.c b/test/battle/move_effect/corrosive_gas.c index cc4110a7e3..84b7c1c70b 100644 --- a/test/battle/move_effect/corrosive_gas.c +++ b/test/battle/move_effect/corrosive_gas.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CORROSIVE_GAS].effect == EFFECT_CORROSIVE_GAS); + ASSUME(GetMoveEffect(MOVE_CORROSIVE_GAS) == EFFECT_CORROSIVE_GAS); } SINGLE_BATTLE_TEST("Corrosive Gas destroys the target's item or fails if the target has no item") @@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Corrosive Gas doesn't destroy the item of a Pokemon with the SINGLE_BATTLE_TEST("Items lost to Corrosive Gas cannot be restored by Recycle") { GIVEN { - ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE); + ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE); PLAYER(SPECIES_WOBBUFFET) {Speed(15); } OPPONENT(SPECIES_WOBBUFFET) {Item(ITEM_ORAN_BERRY); Speed(10); } } WHEN { diff --git a/test/battle/move_effect/cosmic_power.c b/test/battle/move_effect/cosmic_power.c index 3b52fbe046..5c8fe30f67 100644 --- a/test/battle/move_effect/cosmic_power.c +++ b/test/battle/move_effect/cosmic_power.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_COSMIC_POWER].effect == EFFECT_COSMIC_POWER); + ASSUME(GetMoveEffect(MOVE_COSMIC_POWER) == EFFECT_COSMIC_POWER); } SINGLE_BATTLE_TEST("Cosmic Power increases the user's Defense and Sp. Defense by 1 stage each") diff --git a/test/battle/move_effect/court_change.c b/test/battle/move_effect/court_change.c index f3775d0af6..0727baff5e 100644 --- a/test/battle/move_effect/court_change.c +++ b/test/battle/move_effect/court_change.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE); + ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE); } DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the opponent") diff --git a/test/battle/move_effect/curse.c b/test/battle/move_effect/curse.c index 0696dfc4ca..868608caa8 100644 --- a/test/battle/move_effect/curse.c +++ b/test/battle/move_effect/curse.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CURSE].effect == EFFECT_CURSE); + ASSUME(GetMoveEffect(MOVE_CURSE) == EFFECT_CURSE); } SINGLE_BATTLE_TEST("Curse lowers Speed, raises Attack, and raises Defense when used by non-Ghost-types") @@ -67,3 +67,5 @@ SINGLE_BATTLE_TEST("Curse applies to the opponent if user is afflicted by Trick- HP_BAR(opponent, damage: opponentMaxHP / 4); } } + +TO_DO_BATTLE_TEST("Baton Pass passes Cursed status"); diff --git a/test/battle/move_effect/dark_void.c b/test/battle/move_effect/dark_void.c new file mode 100644 index 0000000000..a69d7d6930 --- /dev/null +++ b/test/battle/move_effect/dark_void.c @@ -0,0 +1,42 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID); +} + +SINGLE_BATTLE_TEST("Dark Void inflicts 1-3 turns of sleep") +{ + u32 turns, count; + ASSUME(B_SLEEP_TURNS >= GEN_5); + PARAMETRIZE { turns = 1; } + PARAMETRIZE { turns = 2; } + PARAMETRIZE { turns = 3; } + PASSES_RANDOMLY(1, 3, RNG_SLEEP_TURNS); + GIVEN { + PLAYER(SPECIES_DARKRAI); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DARK_VOID); MOVE(opponent, MOVE_CELEBRATE); } + for (count = 0; count < turns; ++count) + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("The opposing Wobbuffet fell asleep!"); + STATUS_ICON(opponent, sleep: TRUE); + for (count = 0; count < turns; ++count) + { + if (count < turns - 1) + MESSAGE("The opposing Wobbuffet is fast asleep."); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + } + MESSAGE("The opposing Wobbuffet woke up!"); + STATUS_ICON(opponent, none: TRUE); + } +} + +TO_DO_BATTLE_TEST("Dark Void can only be used by Darkrai (Gen7+)"); +TO_DO_BATTLE_TEST("Dark Void can be used by Pokémon other than Darkrai (Gen4-6)"); +TO_DO_BATTLE_TEST("Dark Void can be used by a Pokémon transformed into Darkrai"); diff --git a/test/battle/move_effect/decorate.c b/test/battle/move_effect/decorate.c new file mode 100644 index 0000000000..5eef9dc305 --- /dev/null +++ b/test/battle/move_effect/decorate.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Decorate raises the target's Attack by 2 stages"); +TO_DO_BATTLE_TEST("Decorate raises the target's Sp. Attack by 2 stages"); diff --git a/test/battle/move_effect/defense_curl.c b/test/battle/move_effect/defense_curl.c new file mode 100644 index 0000000000..c8beffe171 --- /dev/null +++ b/test/battle/move_effect/defense_curl.c @@ -0,0 +1,37 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_DEFENSE_CURL) == EFFECT_DEFENSE_CURL); +} + +SINGLE_BATTLE_TEST("Defense Curl raises Defense by 1 stage", s16 damage) +{ + bool32 raiseDefense; + PARAMETRIZE { raiseDefense = FALSE; } + PARAMETRIZE { raiseDefense = TRUE; } + GIVEN { + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseDefense) TURN { MOVE(player, MOVE_DEFENSE_CURL); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + if (raiseDefense) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFENSE_CURL, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Defense rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[0].damage); + } +} + +TO_DO_BATTLE_TEST("Defense Curl doubles the power of Rollout and Ice Ball"); +TO_DO_BATTLE_TEST("Defense Curl's effect cannot be stacked"); +TO_DO_BATTLE_TEST("Defense Curl's effect is removed when switching out"); +TO_DO_BATTLE_TEST("Baton Pass doesn't pass Defense Curl's effect"); diff --git a/test/battle/move_effect/defense_down.c b/test/battle/move_effect/defense_down.c index 0552a9c67e..9691b4a1c2 100644 --- a/test/battle/move_effect/defense_down.c +++ b/test/battle/move_effect/defense_down.c @@ -3,16 +3,16 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAIL_WHIP].effect == EFFECT_DEFENSE_DOWN); + ASSUME(GetMoveEffect(MOVE_TAIL_WHIP) == EFFECT_DEFENSE_DOWN); } -SINGLE_BATTLE_TEST("Tail Whip lowers Defense", s16 damage) +SINGLE_BATTLE_TEST("Tail Whip lowers Defense by 1 stage", s16 damage) { bool32 lowerDefense; PARAMETRIZE { lowerDefense = FALSE; } PARAMETRIZE { lowerDefense = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/defense_down_2.c b/test/battle/move_effect/defense_down_2.c new file mode 100644 index 0000000000..961e2de02f --- /dev/null +++ b/test/battle/move_effect/defense_down_2.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2); +} + +SINGLE_BATTLE_TEST("Screech lowers Defense by 2 stages", s16 damage) +{ + bool32 lowerDefense; + PARAMETRIZE { lowerDefense = FALSE; } + PARAMETRIZE { lowerDefense = TRUE; } + GIVEN { + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (lowerDefense) TURN { MOVE(player, MOVE_SCREECH); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (lowerDefense) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCREECH, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("The opposing Wobbuffet's Defense harshly fell!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} diff --git a/test/battle/move_effect/defense_up.c b/test/battle/move_effect/defense_up.c index 513d6e1c29..c83f2c01c5 100644 --- a/test/battle/move_effect/defense_up.c +++ b/test/battle/move_effect/defense_up.c @@ -3,16 +3,16 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HARDEN].effect == EFFECT_DEFENSE_UP); + ASSUME(GetMoveEffect(MOVE_HARDEN) == EFFECT_DEFENSE_UP); } -SINGLE_BATTLE_TEST("Harden raises Defense", s16 damage) +SINGLE_BATTLE_TEST("Harden raises Defense by 1 stage", s16 damage) { bool32 raiseDefense; PARAMETRIZE { raiseDefense = FALSE; } PARAMETRIZE { raiseDefense = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/defense_up_2.c b/test/battle/move_effect/defense_up_2.c new file mode 100644 index 0000000000..59ca5c1af9 --- /dev/null +++ b/test/battle/move_effect/defense_up_2.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); +} + +SINGLE_BATTLE_TEST("Iron Defense raises Defense by 2 stages", s16 damage) +{ + bool32 raiseDefense; + PARAMETRIZE { raiseDefense = FALSE; } + PARAMETRIZE { raiseDefense = TRUE; } + GIVEN { + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseDefense) TURN { MOVE(player, MOVE_IRON_DEFENSE); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + if (raiseDefense) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Defense sharply rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.0), results[0].damage); + } +} diff --git a/test/battle/move_effect/defense_up_3.c b/test/battle/move_effect/defense_up_3.c new file mode 100644 index 0000000000..040537c1d4 --- /dev/null +++ b/test/battle/move_effect/defense_up_3.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_COTTON_GUARD) == EFFECT_DEFENSE_UP_3); +} + +SINGLE_BATTLE_TEST("Cotton Guard raises Defense by 3 stages", s16 damage) +{ + bool32 raiseDefense; + PARAMETRIZE { raiseDefense = FALSE; } + PARAMETRIZE { raiseDefense = TRUE; } + GIVEN { + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseDefense) TURN { MOVE(player, MOVE_COTTON_GUARD); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + if (raiseDefense) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_GUARD, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Defense drastically rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.5), results[0].damage); + } +} diff --git a/test/battle/move_effect/defog.c b/test/battle/move_effect/defog.c index d5838d7ffd..3d0a46806c 100644 --- a/test/battle/move_effect/defog.c +++ b/test/battle/move_effect/defog.c @@ -3,23 +3,23 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DEFOG].effect == EFFECT_DEFOG); - ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT); - ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN); - ASSUME(gMovesInfo[MOVE_MIST].effect == EFFECT_MIST); - ASSUME(gMovesInfo[MOVE_SAFEGUARD].effect == EFFECT_SAFEGUARD); - ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL); - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); - ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES); - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_SCREECH].effect == EFFECT_DEFENSE_DOWN_2); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveEffect(MOVE_DEFOG) == EFFECT_DEFOG); + ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT); + ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN); + ASSUME(GetMoveEffect(MOVE_MIST) == EFFECT_MIST); + ASSUME(GetMoveEffect(MOVE_SAFEGUARD) == EFFECT_SAFEGUARD); + ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL); + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); + ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); } -SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1") +SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 stage") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -51,7 +51,8 @@ SINGLE_BATTLE_TEST("Defog does not lower evasiveness if target behind Substitute } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light Screen from opponent's side", s16 damagePhysical, s16 damageSpecial) +TO_DO_BATTLE_TEST("Defog doesn't remove Reflect or Light Screen from the user's side"); +DOUBLE_BATTLE_TEST("Defog removes Reflect and Light Screen from target's side", s16 damagePhysical, s16 damageSpecial) { u16 move; @@ -71,8 +72,6 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light ANIMATION(ANIM_TYPE_MOVE, MOVE_LIGHT_SCREEN, opponentRight); ANIMATION(ANIM_TYPE_MOVE, move, playerLeft); if (move == MOVE_DEFOG) { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); - MESSAGE("The opposing Wobbuffet's evasiveness fell!"); MESSAGE("The opposing team's Reflect wore off!"); MESSAGE("The opposing team's Light Screen wore off!"); } @@ -86,7 +85,8 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard from opponent's side") +TO_DO_BATTLE_TEST("Defog doesn't remove Mist or Safeguard from the user's side"); +DOUBLE_BATTLE_TEST("Defog removes Mist and Safeguard from target's side") { u16 move; @@ -105,7 +105,6 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard ANIMATION(ANIM_TYPE_MOVE, MOVE_MIST, opponentLeft); ANIMATION(ANIM_TYPE_MOVE, MOVE_SAFEGUARD, opponentRight); if (move == MOVE_DEFOG) { - MESSAGE("The opposing Wobbuffet is protected by the mist!"); ANIMATION(ANIM_TYPE_MOVE, move, playerLeft); MESSAGE("The opposing team's Mist wore off!"); MESSAGE("The opposing team's Safeguard wore off!"); @@ -131,7 +130,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side (Gen 6+)") +TO_DO_BATTLE_TEST("Defog removes Stealth Rock and Sticky Web from target's side"); +TO_DO_BATTLE_TEST("Defog doesn't remove Stealth Rock or Sticky Web from user's side (Gen 4-5)"); +DOUBLE_BATTLE_TEST("Defog removes Stealth Rock and Sticky Web from user's side (Gen 6+)") { u16 move; @@ -151,13 +152,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponentLeft); ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentRight); ANIMATION(ANIM_TYPE_MOVE, move, playerLeft); - if (move == MOVE_DEFOG) { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); - MESSAGE("The opposing Wobbuffet's evasiveness fell!"); - if (B_DEFOG_EFFECT_CLEARING >= GEN_6) { - MESSAGE("The pointed stones disappeared from around your team!"); - MESSAGE("The sticky web has disappeared from the ground around your team!"); - } + if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6) { + MESSAGE("The pointed stones disappeared from around your team!"); + MESSAGE("The sticky web has disappeared from the ground around your team!"); } // Switch happens SWITCH_OUT_MESSAGE("Wobbuffet"); @@ -181,7 +178,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S } } -SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player's side") +TO_DO_BATTLE_TEST("Defog removes Spikes from target's side"); +TO_DO_BATTLE_TEST("Defog doesn't remove Spikes from user's side (Gen 4-5)"); +SINGLE_BATTLE_TEST("Defog removes Spikes from user's side (Gen 6+)") { u16 move; @@ -197,12 +196,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, opponent); ANIMATION(ANIM_TYPE_MOVE, move, player); - if (move == MOVE_DEFOG) { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("The opposing Wobbuffet's evasiveness fell!"); - if (B_DEFOG_EFFECT_CLEARING >= GEN_6) - MESSAGE("The spikes disappeared from the ground around your team!"); - } + if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6) + MESSAGE("The spikes disappeared from the ground around your team!"); // Switch happens SWITCH_OUT_MESSAGE("Wobbuffet"); SEND_IN_MESSAGE("Wobbuffet"); @@ -219,7 +214,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player } } -SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)") +TO_DO_BATTLE_TEST("Defog doesn't remove terrain (Gen 4-7)"); +SINGLE_BATTLE_TEST("Defog removes terrain (Gen 8+)") { u16 move; @@ -235,8 +231,6 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)") } SCENE { ANIMATION(ANIM_TYPE_MOVE, move, player); ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFOG, opponent); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's evasiveness fell!"); if (B_DEFOG_EFFECT_CLEARING >= GEN_8) { if (move == MOVE_PSYCHIC_TERRAIN) { MESSAGE("The weirdness disappeared from the battlefield!"); @@ -263,7 +257,9 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)") } } -SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from opponent's side") +TO_DO_BATTLE_TEST("Defog removes Toxic Spikes from target's side"); +TO_DO_BATTLE_TEST("Defog doesn't remove Toxic Spikes from user's side (Gen 4-5)"); +SINGLE_BATTLE_TEST("Defog removes Toxic Spikes from user's side (Gen 6+)") { u16 move; @@ -279,12 +275,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC_SPIKES, player); ANIMATION(ANIM_TYPE_MOVE, move, opponent); - if (move == MOVE_DEFOG) { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's evasiveness fell!"); - if (B_DEFOG_EFFECT_CLEARING >= GEN_6) - MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); - } + if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6) + MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); // Switch happens MESSAGE("2 sent out Wobbuffet!"); if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) { @@ -302,14 +294,15 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Aurora Veil from player's side", s16 damagePhysical, s16 damageSpecial) +TO_DO_BATTLE_TEST("Defog doesn't remove Aurora Veil from the user's side"); +DOUBLE_BATTLE_TEST("Defog removes Aurora Veil from target's side", s16 damagePhysical, s16 damageSpecial) { u16 move; PARAMETRIZE { move = MOVE_DEFOG; } PARAMETRIZE { move = MOVE_CELEBRATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE); PLAYER(SPECIES_GLALIE) { Speed(4); } PLAYER(SPECIES_GLALIE) { Speed(3); } @@ -338,10 +331,10 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Aurora Veil from p } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes everything it can") +DOUBLE_BATTLE_TEST("Defog removes everything it can") { GIVEN { - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE); PLAYER(SPECIES_GLALIE) { Speed(4); } PLAYER(SPECIES_GLALIE) { Speed(3); } diff --git a/test/battle/move_effect/destiny_bond.c b/test/battle/move_effect/destiny_bond.c index 7291fe7fb3..ecb8b1d3ef 100644 --- a/test/battle/move_effect/destiny_bond.c +++ b/test/battle/move_effect/destiny_bond.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DESTINY_BOND].effect == EFFECT_DESTINY_BOND); + ASSUME(GetMoveEffect(MOVE_DESTINY_BOND) == EFFECT_DESTINY_BOND); } SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the attack") @@ -77,3 +77,35 @@ SINGLE_BATTLE_TEST("Destiny Bond does not fail if used after failing in Gen 7+") ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); } } + +// can't be used at all in Raid, see "Documenting Dynamax" +SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); } + } WHEN { + TURN { MOVE(opponent, MOVE_DESTINY_BOND); MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); } + } SCENE { + MESSAGE("The opposing Wobbuffet used Destiny Bond!"); + MESSAGE("Wobbuffet used Max Strike!"); + MESSAGE("The opposing Wobbuffet fainted!"); + NONE_OF { HP_BAR(player); } + } +} + +TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Move"); +TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Sleep"); +TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Paralysis"); +TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Flinching"); +TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Sandstorm"); +TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Leech Seed"); +TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Future Sight"); +TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Focus Sash"); +TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Sturdy"); +TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Magic Guard"); +TO_DO_BATTLE_TEST("Destiny Bond's effect can trigger on the next turn if the user hasn't moved yet"); +TO_DO_BATTLE_TEST("Destiny Bond can be used multiple times in a row (Gen 2-6)"); +TO_DO_BATTLE_TEST("Destiny Bond always fails if it was successfully used the previous turn (Gen 7+)"); +TO_DO_BATTLE_TEST("Destiny Bond cannot be used in Raids"); + diff --git a/test/battle/move_effect/disable.c b/test/battle/move_effect/disable.c new file mode 100644 index 0000000000..9864b360e2 --- /dev/null +++ b/test/battle/move_effect/disable.c @@ -0,0 +1,20 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Disable prevents the target from using a random move (Gen 1)"); +TO_DO_BATTLE_TEST("Disable prevents the target from using the last move used (Gen 2+)"); +TO_DO_BATTLE_TEST("Disable fails if one of the target's moves is already disabled"); +TO_DO_BATTLE_TEST("Disable fails if the target haven't used a move yet (Gen 2+)"); +TO_DO_BATTLE_TEST("Disable fails if the last move used was Struggle (Gen 2+)"); +TO_DO_BATTLE_TEST("Disable fails if the last move used was a Max Move"); +TO_DO_BATTLE_TEST("Disabled moves can still be used via Sleep Talk"); +TO_DO_BATTLE_TEST("Disabled moves can still be used via Metronome"); +TO_DO_BATTLE_TEST("Disabled moves can still be used via Mirror Move"); +TO_DO_BATTLE_TEST("Disable lasts 0-7 turns (Gen 1)"); +TO_DO_BATTLE_TEST("Disable lasts 2-8 turns (Gen 2)"); +TO_DO_BATTLE_TEST("Disable lasts 2-5 turns (Gen 3)"); +TO_DO_BATTLE_TEST("Disable lasts 4-7 turns (Gen 4)"); +TO_DO_BATTLE_TEST("Disable lasts 4 turns (Gen 5+)"); +TO_DO_BATTLE_TEST("Disable's timer only counts down when trying to use a move (Gen 1-2)"); +TO_DO_BATTLE_TEST("Disable's timer counts down regardless of the action (Gen 3+)"); +TO_DO_BATTLE_TEST("Baton Pass doesn't pass Disable's effect"); diff --git a/test/battle/move_effect/do_nothing.c b/test/battle/move_effect/do_nothing.c new file mode 100644 index 0000000000..60ff198b52 --- /dev/null +++ b/test/battle/move_effect/do_nothing.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Splash does nothing"); diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c index a43a149dc8..af144ecee5 100644 --- a/test/battle/move_effect/doodle.c +++ b/test/battle/move_effect/doodle.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DOODLE].effect == EFFECT_DOODLE); + ASSUME(GetMoveEffect(MOVE_DOODLE) == EFFECT_DOODLE); } DOUBLE_BATTLE_TEST("Doodle gives the target's ability to user and ally") diff --git a/test/battle/move_effect_secondary/double_power_on_arg_status.c b/test/battle/move_effect/double_power_on_arg_status.c similarity index 84% rename from test/battle/move_effect_secondary/double_power_on_arg_status.c rename to test/battle/move_effect/double_power_on_arg_status.c index d147264470..d733d04c4f 100644 --- a/test/battle/move_effect_secondary/double_power_on_arg_status.c +++ b/test/battle/move_effect/double_power_on_arg_status.c @@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Hex deals double damage to foes with a status", s16 damage) PARAMETRIZE { status1 = STATUS1_PARALYSIS; } PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } GIVEN { - ASSUME(gMovesInfo[MOVE_HEX].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_HEX].argument == STATUS1_ANY); + ASSUME(GetMoveEffect(MOVE_HEX) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_HEX) == STATUS1_ANY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); } } WHEN { @@ -36,8 +36,8 @@ SINGLE_BATTLE_TEST("Venoshock's power doubles if the target is poisoned/badly po PARAMETRIZE { status1 = STATUS1_POISON; } PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } GIVEN { - ASSUME(gMovesInfo[MOVE_VENOSHOCK].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_VENOSHOCK].argument == STATUS1_PSN_ANY); + ASSUME(GetMoveEffect(MOVE_VENOSHOCK) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_VENOSHOCK) == STATUS1_PSN_ANY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); } } WHEN { diff --git a/test/battle/move_effect/dragon_cheer.c b/test/battle/move_effect/dragon_cheer.c new file mode 100644 index 0000000000..1e28c6d4b3 --- /dev/null +++ b/test/battle/move_effect/dragon_cheer.c @@ -0,0 +1,77 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Dragon Cheer fails in a single battle") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DRAGON_CHEER); } + } SCENE { + MESSAGE("But it failed!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by one on non-Dragon types") +{ + PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); + GIVEN { + ASSUME(B_CRIT_CHANCE >= GEN_7); + ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0); + ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); + MESSAGE("Wynaut is getting pumped!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); + MESSAGE("A critical hit!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by two on Dragon types") +{ + PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT); + GIVEN { + ASSUME(B_CRIT_CHANCE >= GEN_7); + ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0); + ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_DRATINI); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft); + MESSAGE("Dratini is getting pumped!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); + MESSAGE("A critical hit!"); + } +} + +DOUBLE_BATTLE_TEST("Dragon Cheer fails if critical hit stage was already increased by Focus Energy") +{ + GIVEN { + ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1); + ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY); + ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FOCUS_ENERGY); MOVE(playerRight, MOVE_DRAGON_CHEER, target: playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, playerLeft); + MESSAGE("But it failed!"); + } +} + +TO_DO_BATTLE_TEST("Baton Pass passes Dragon Cheer's effect"); diff --git a/test/battle/move_effect/dragon_dance.c b/test/battle/move_effect/dragon_dance.c new file mode 100644 index 0000000000..52587cc098 --- /dev/null +++ b/test/battle/move_effect/dragon_dance.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Dragon Dance increases Attack and Speed by one stage each"); diff --git a/test/battle/move_effect/dragon_darts.c b/test/battle/move_effect/dragon_darts.c index dfe629896f..9e178f67c8 100644 --- a/test/battle/move_effect/dragon_darts.c +++ b/test/battle/move_effect/dragon_darts.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS); + ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS); ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY); } @@ -23,170 +23,148 @@ SINGLE_BATTLE_TEST("Dragon Darts strikes twice") DOUBLE_BATTLE_TEST("Dragon Darts strikes each opponent once in a double battle") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *secondaryTarget = NULL; + PARAMETRIZE { chosenTarget = opponentLeft; secondaryTarget = opponentRight; } + PARAMETRIZE { chosenTarget = opponentRight; secondaryTarget = opponentLeft; } + GIVEN { PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } + TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); + HP_BAR(chosenTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(secondaryTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } DOUBLE_BATTLE_TEST("Dragon Darts strikes the ally twice if the target protects") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *secondaryTarget = NULL; + PARAMETRIZE { chosenTarget = opponentLeft; secondaryTarget = opponentRight; } + PARAMETRIZE { chosenTarget = opponentRight; secondaryTarget = opponentLeft; } GIVEN { PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponentLeft, MOVE_PROTECT); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } + TURN { MOVE(chosenTarget, MOVE_PROTECT); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, chosenTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(secondaryTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(secondaryTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } -DOUBLE_BATTLE_TEST("Dragon Darts strikes the right ally twice if the target is a fairy type") +DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is Fairy-type") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + u32 speciesLeft, speciesRight; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; speciesLeft = SPECIES_CLEFAIRY; speciesRight = SPECIES_WOBBUFFET; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; speciesLeft = SPECIES_CLEFAIRY; speciesRight = SPECIES_WOBBUFFET; } + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; speciesLeft = SPECIES_WOBBUFFET; speciesRight = SPECIES_CLEFAIRY; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; speciesLeft = SPECIES_WOBBUFFET; speciesRight = SPECIES_CLEFAIRY; } GIVEN { + ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_CLEFAIRY); - OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(speciesLeft); + OPPONENT(speciesRight); } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } + TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } -DOUBLE_BATTLE_TEST("Dragon Darts strikes the left ally twice if the target is a fairy type") +DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if electrified and the other one has Volt Absorb") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + u32 abilityLeft, abilityRight; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; abilityLeft = ABILITY_WATER_ABSORB; abilityRight = ABILITY_VOLT_ABSORB; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; abilityLeft = ABILITY_WATER_ABSORB; abilityRight = ABILITY_VOLT_ABSORB; } + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; abilityLeft = ABILITY_VOLT_ABSORB; abilityRight = ABILITY_WATER_ABSORB; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; abilityLeft = ABILITY_VOLT_ABSORB; abilityRight = ABILITY_WATER_ABSORB; } GIVEN { + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_CLEFAIRY); - OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_LANTURN) { Ability(abilityLeft); }; + OPPONENT(SPECIES_LANTURN) { Ability(abilityRight); }; } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); } + TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } -DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if electrified and right ally has Volt Absorb") +DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if electrified and the other one has Motor Drive") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + u32 abilityLeft, abilityRight; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_MOTOR_DRIVE; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_MOTOR_DRIVE; } + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; abilityLeft = ABILITY_MOTOR_DRIVE; abilityRight = ABILITY_VITAL_SPIRIT; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; abilityLeft = ABILITY_MOTOR_DRIVE; abilityRight = ABILITY_VITAL_SPIRIT; } GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }; + OPPONENT(SPECIES_ELECTIVIRE) { Ability(abilityLeft); }; + OPPONENT(SPECIES_ELECTIVIRE) { Ability(abilityRight); }; } WHEN { - TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); } + TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } -DOUBLE_BATTLE_TEST("Dragon Darts strikes right ally twice if electrified and left ally has Volt Absorb") +DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is in a semi-invulnerable turn") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; } GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }; - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); - MESSAGE("The Pokémon was hit 2 time(s)!"); - } -} - -DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if electrified and right ally has Motor Drive") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); }; - } WHEN { - TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); - MESSAGE("The Pokémon was hit 2 time(s)!"); - } -} - -DOUBLE_BATTLE_TEST("Dragon Darts strikes right ally twice if electrified and left ally has Motor Drive") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); }; - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); - ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); - MESSAGE("The Pokémon was hit 2 time(s)!"); - } -} - - -DOUBLE_BATTLE_TEST("Dragon Darts strikes the ally twice if the target is in a semi-invulnerable turn") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponentLeft, MOVE_FLY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } + TURN { MOVE(chosenTarget, MOVE_FLY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_FLY, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLY, chosenTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } @@ -210,39 +188,49 @@ DOUBLE_BATTLE_TEST("Dragon Darts is not effected by Wide Guard") } } -DOUBLE_BATTLE_TEST("Dragon Darts strikes hit the ally if the target fainted") +DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is fainted") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + u32 hpLeft, hpRight; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; hpLeft = 1; hpRight = 101; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; hpLeft = 101; hpRight = 1; } GIVEN { PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { HP(1); } - OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(hpLeft); } + OPPONENT(SPECIES_WOBBUFFET) { HP(hpRight); } } WHEN { - TURN { MOVE(playerRight, MOVE_SONIC_BOOM, target: opponentLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); } + TURN { MOVE(playerRight, MOVE_SONIC_BOOM, target: chosenTarget); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SONIC_BOOM, playerRight); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentRight); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if one strike misses") { + struct BattlePokemon *chosenTarget = NULL; + struct BattlePokemon *finalTarget = NULL; + u32 itemLeft, itemRight; + PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; itemLeft = ITEM_BRIGHT_POWDER; itemRight = ITEM_NONE; } + PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; itemLeft = ITEM_NONE; itemRight = ITEM_BRIGHT_POWDER; } GIVEN { PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_BRIGHT_POWDER); }; + OPPONENT(SPECIES_WOBBUFFET) { Item(itemLeft); }; + OPPONENT(SPECIES_WOBBUFFET) { Item(itemRight); }; } WHEN { - TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight, hit: FALSE); } + TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget, hit: FALSE); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); + HP_BAR(finalTarget); ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft); - HP_BAR(opponentLeft); + HP_BAR(finalTarget); MESSAGE("The Pokémon was hit 2 time(s)!"); } } diff --git a/test/battle/move_effect/dream_eater.c b/test/battle/move_effect/dream_eater.c index 7dfa6525d9..b840e9860c 100644 --- a/test/battle/move_effect/dream_eater.c +++ b/test/battle/move_effect/dream_eater.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DREAM_EATER].effect == EFFECT_DREAM_EATER); + ASSUME(GetMoveEffect(MOVE_DREAM_EATER) == EFFECT_DREAM_EATER); } SINGLE_BATTLE_TEST("Dream Eater recovers 50% of the damage dealt") @@ -54,3 +54,7 @@ SINGLE_BATTLE_TEST("Dream Eater fails if Heal Block applies") } } } + +TO_DO_BATTLE_TEST("Dream Eater works on targets with Comatose"); +TO_DO_BATTLE_TEST("Dream Eater fails if the target is behind a Substitute (Gen 1-4)"); +TO_DO_BATTLE_TEST("Dream Eater works if the target is behind a Substitute (Gen 5+)"); diff --git a/test/battle/move_effect/dynamax_double_dmg.c b/test/battle/move_effect/dynamax_double_dmg.c new file mode 100644 index 0000000000..c19ba5ecbc --- /dev/null +++ b/test/battle/move_effect/dynamax_double_dmg.c @@ -0,0 +1,20 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Dynamax Cannon causes double damage to Dynamaxed Pokemon", s16 damage) +{ + u32 dynamax; + PARAMETRIZE { dynamax = GIMMICK_NONE; } + PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; } + GIVEN { + ASSUME(GetMoveEffect(MOVE_DYNAMAX_CANNON) == EFFECT_DYNAMAX_DOUBLE_DMG); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_DYNAMAX_CANNON); } + } SCENE { + HP_BAR(player, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage); + } +} diff --git a/test/battle/move_effect/earthquake.c b/test/battle/move_effect/earthquake.c index 93955e15b4..2cbf3b32c5 100644 --- a/test/battle/move_effect/earthquake.c +++ b/test/battle/move_effect/earthquake.c @@ -10,8 +10,8 @@ SINGLE_BATTLE_TEST("Earthquake's and Bulldoze's damage is halved when Grassy Ter PARAMETRIZE { terrain = FALSE; move = MOVE_BULLDOZE; } // 2 PARAMETRIZE { terrain = TRUE; move = MOVE_BULLDOZE; } // 3 GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].effect == EFFECT_EARTHQUAKE); - ASSUME(gMovesInfo[MOVE_BULLDOZE].effect == EFFECT_EARTHQUAKE); + ASSUME(GetMoveEffect(MOVE_EARTHQUAKE) == EFFECT_EARTHQUAKE); + ASSUME(GetMoveEffect(MOVE_BULLDOZE) == EFFECT_EARTHQUAKE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/echoed_voice.c b/test/battle/move_effect/echoed_voice.c new file mode 100644 index 0000000000..3c36270454 --- /dev/null +++ b/test/battle/move_effect/echoed_voice.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Echoed Voice's power is multiplied for every consecutive turn used, capped at 5"); +TO_DO_BATTLE_TEST("Echoed Voice's power is reset when using a different move"); +TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it misses"); +TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it's blocked by Protect"); diff --git a/test/battle/terrain/electric.c b/test/battle/move_effect/electric_terrain.c similarity index 74% rename from test/battle/terrain/electric.c rename to test/battle/move_effect/electric_terrain.c index b3811d056c..bf6d2536e6 100644 --- a/test/battle/terrain/electric.c +++ b/test/battle/move_effect/electric_terrain.c @@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Electric Terrain protects grounded battlers from falling asl } } -SINGLE_BATTLE_TEST("Electric Terrain activates Electric Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Electric!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_ELECTRIC); - } -} - SINGLE_BATTLE_TEST("Electric Terrain increases power of Electric-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/electrify.c b/test/battle/move_effect/electrify.c new file mode 100644 index 0000000000..71373cdd58 --- /dev/null +++ b/test/battle/move_effect/electrify.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn"); +TO_DO_BATTLE_TEST("Electrify can change status moves to Electric-type"); // Test type immunity diff --git a/test/battle/move_effect/electro_ball.c b/test/battle/move_effect/electro_ball.c new file mode 100644 index 0000000000..a74445c00c --- /dev/null +++ b/test/battle/move_effect/electro_ball.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electro Ball inflicts more damage the faster the user is compared to the target"); +TO_DO_BATTLE_TEST("Electro Ball considers speed modifiers"); // Stat modifiers, paralysis, Iron Ball, Abilities diff --git a/test/battle/move_effect/embargo.c b/test/battle/move_effect/embargo.c index 81939a6d56..3e86b60b0b 100644 --- a/test/battle/move_effect/embargo.c +++ b/test/battle/move_effect/embargo.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_EMBARGO].effect == EFFECT_EMBARGO); + ASSUME(GetMoveEffect(MOVE_EMBARGO) == EFFECT_EMBARGO); } SINGLE_BATTLE_TEST("Embargo blocks the effect of an affected Pokémon's held item") diff --git a/test/battle/move_effect/encore.c b/test/battle/move_effect/encore.c index ec68297ca0..2d1863da6b 100644 --- a/test/battle/move_effect/encore.c +++ b/test/battle/move_effect/encore.c @@ -3,94 +3,59 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); } -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used before move") +SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns: Encore used before move") { + struct BattlePokemon *encoreUser = NULL; + struct BattlePokemon *encoreTarget = NULL; + u32 speedPlayer, speedOpponent; + PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 10; speedOpponent = 20; } + PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 20; speedOpponent = 10; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(10); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(20); } + PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); } } WHEN { - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_CELEBRATE); } - TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_CELEBRATE); } - // TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { MOVE(player, MOVE_SPLASH); } + TURN { MOVE(encoreUser, MOVE_CELEBRATE); MOVE(encoreTarget, MOVE_CELEBRATE); } + TURN { MOVE(encoreUser, MOVE_ENCORE); MOVE(encoreTarget, MOVE_CELEBRATE); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { MOVE(encoreTarget, MOVE_SPLASH); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget); } } SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used after move") { + struct BattlePokemon *encoreUser = NULL; + struct BattlePokemon *encoreTarget = NULL; + u32 speedPlayer, speedOpponent; + PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 20; speedOpponent = 10; } + PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 10; speedOpponent = 20; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(10); } + PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); } } WHEN { - TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_ENCORE); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { MOVE(player, MOVE_SPLASH); } + TURN { MOVE(encoreTarget, MOVE_CELEBRATE); MOVE(encoreUser, MOVE_ENCORE); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { MOVE(encoreTarget, MOVE_SPLASH); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player); - } -} - -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used before move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(10); } - } WHEN { - TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } - TURN { MOVE(player, MOVE_ENCORE); MOVE(opponent, MOVE_CELEBRATE); } - // TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { MOVE(opponent, MOVE_SPLASH); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent); - } -} - -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used after move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(10); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(20); } - } WHEN { - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_ENCORE); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { MOVE(opponent, MOVE_SPLASH); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget); } } @@ -121,3 +86,44 @@ SINGLE_BATTLE_TEST("Encore overrides the chosen move if it occurs first") ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); } } + +SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); } + TURN { MOVE(player, MOVE_EMBER); } + } SCENE { + MESSAGE("Wobbuffet used Max Strike!"); + MESSAGE("The opposing Wobbuffet used Encore!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Max Flare!"); + } +} + +SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; + } WHEN { + TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); } + TURN { MOVE(player, MOVE_ARM_THRUST); } + TURN { MOVE(player, MOVE_ARM_THRUST); } + TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("The opposing Wobbuffet used Encore!"); + MESSAGE("Wobbuffet used Arm Thrust!"); + } +} + +TO_DO_BATTLE_TEST("Encore's effect ends if the encored move runs out of PP"); +TO_DO_BATTLE_TEST("Encore lasts for 2-6 turns (Gen 2-3)"); +TO_DO_BATTLE_TEST("Encore lasts for 4-8 turns (Gen 4)"); +TO_DO_BATTLE_TEST("Encore lasts for 3 turns (Gen 5+)"); +TO_DO_BATTLE_TEST("Encore randomly chooses an opponent target"); diff --git a/test/battle/move_effect/endeavor.c b/test/battle/move_effect/endeavor.c index 7080ee9c28..43786c29b3 100644 --- a/test/battle/move_effect/endeavor.c +++ b/test/battle/move_effect/endeavor.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR); + ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR); } SINGLE_BATTLE_TEST("Endeavor causes the target's HP to equal the user's current HP") @@ -20,4 +20,4 @@ SINGLE_BATTLE_TEST("Endeavor causes the target's HP to equal the user's current } } TO_DO_BATTLE_TEST("Endeavor does not change HP if the target has less HP than the user, but still plays the animation") -TO_DO_BATTLE_TEST("Endeavor doesn't ignore type immunity") // Ghost types +TO_DO_BATTLE_TEST("Endeavor fails on Ghost-type Pokémon"); diff --git a/test/battle/move_effect/endure.c b/test/battle/move_effect/endure.c new file mode 100644 index 0000000000..5401321162 --- /dev/null +++ b/test/battle/move_effect/endure.c @@ -0,0 +1,35 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Endure allows the user to survive any attack with 1 HP left"); + +SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_ENDURE) == EFFECT_ENDURE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + } WHEN { + TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + MESSAGE("The Pokémon was hit 5 time(s)!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Defense fell!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Speed rose!"); + } +} + +TO_DO_BATTLE_TEST("Endure's success rate decreases for every consecutively used turn"); +TO_DO_BATTLE_TEST("Endure uses the same counter as Protect"); +TO_DO_BATTLE_TEST("Endure doesn't trigger effects that require damage to be done to the Pokémon (Gen 2-4)"); // Eg. Rough Skin +TO_DO_BATTLE_TEST("Endure triggers effects that require damage to be done to the Pokémon (Gen 5+)"); // Eg. Rough Skin +TO_DO_BATTLE_TEST("Endure doesn't protect against Future Sight (Gen 2-4)"); +TO_DO_BATTLE_TEST("Endure protects against Future Sight (Gen 5+)"); diff --git a/test/battle/move_effect/entrainment.c b/test/battle/move_effect/entrainment.c new file mode 100644 index 0000000000..b43f6dcbc1 --- /dev/null +++ b/test/battle/move_effect/entrainment.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Entrainment changes the target's Ability to match the user's"); +TO_DO_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag"); +TO_DO_BATTLE_TEST("Entrainment fails if the targets's ability has cantBeOverwritten flag"); diff --git a/test/battle/move_effect/evasion_down.c b/test/battle/move_effect/evasion_down.c new file mode 100644 index 0000000000..ecc0db135b --- /dev/null +++ b/test/battle/move_effect/evasion_down.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 2-5)"); diff --git a/test/battle/move_effect/evasion_down_2.c b/test/battle/move_effect/evasion_down_2.c new file mode 100644 index 0000000000..7584406e4c --- /dev/null +++ b/test/battle/move_effect/evasion_down_2.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 6+)"); diff --git a/test/battle/move_effect/evasion_up.c b/test/battle/move_effect/evasion_up.c index 7058694e9d..529a32c4f1 100644 --- a/test/battle/move_effect/evasion_up.c +++ b/test/battle/move_effect/evasion_up.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP); + ASSUME(GetMoveEffect(MOVE_DOUBLE_TEAM) == EFFECT_EVASION_UP); } -SINGLE_BATTLE_TEST("Double Team raises Evasion") +SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage") { - PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY); + PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SCRATCH) * 3 / 4, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100); + ASSUME(GetMoveAccuracy(MOVE_SCRATCH) == 100); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/evasion_up_2.c b/test/battle/move_effect/evasion_up_2.c new file mode 100644 index 0000000000..cd5cb543a9 --- /dev/null +++ b/test/battle/move_effect/evasion_up_2.c @@ -0,0 +1,28 @@ +#include "global.h" +#include "test/battle.h" + +// There's no move with EFFECT_EVASION_UP_2 effect. Below is a theoretical test. + +/* +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_X].effect == EFFECT_EVASION_UP_2); +} + +SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage") +{ + PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 5, 100, RNG_ACCURACY); + GIVEN { + ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_X); MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_X, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's evasiveness sharply rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); + } +} +*/ diff --git a/test/battle/move_effect/expanding_force.c b/test/battle/move_effect/expanding_force.c new file mode 100644 index 0000000000..74b78fdd86 --- /dev/null +++ b/test/battle/move_effect/expanding_force.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Expanding Force's power increases by 50% if the user is affected by Psychic Terrain"); diff --git a/test/battle/move_effect/explosion.c b/test/battle/move_effect/explosion.c index f383ecb1a2..52eec1a8e2 100644 --- a/test/battle/move_effect/explosion.c +++ b/test/battle/move_effect/explosion.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); } SINGLE_BATTLE_TEST("Explosion causes the user to faint") @@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Explosion causes the user to faint even if it misses") SINGLE_BATTLE_TEST("Explosion causes the user to faint even if it has no effect") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_EXPLOSION) == TYPE_NORMAL); ASSUME(gSpeciesInfo[SPECIES_GASTLY].types[0] == TYPE_GHOST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GASTLY); diff --git a/test/battle/move_effect/extreme_evoboost.c b/test/battle/move_effect/extreme_evoboost.c new file mode 100644 index 0000000000..c43a6f7374 --- /dev/null +++ b/test/battle/move_effect/extreme_evoboost.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Extreme Evoboost increases the user's Attack, Defense, Special Attack, Special Defense, and Speed stats by 2 stages each"); diff --git a/test/battle/move_effect/fail_if_not_arg_type.c b/test/battle/move_effect/fail_if_not_arg_type.c index 9e8d005d8b..368c3410c0 100644 --- a/test/battle/move_effect/fail_if_not_arg_type.c +++ b/test/battle/move_effect/fail_if_not_arg_type.c @@ -4,8 +4,8 @@ SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type") { GIVEN { - ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); + ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE); ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE); PLAYER(SPECIES_CYNDAQUIL); @@ -24,8 +24,8 @@ SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type") SINGLE_BATTLE_TEST("Burn Up fails if the user isn't a Fire-type") { GIVEN { - ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); + ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -41,8 +41,8 @@ SINGLE_BATTLE_TEST("Burn Up fails if the user isn't a Fire-type") SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type if enemy faints") { GIVEN { - ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); + ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE); ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE); PLAYER(SPECIES_CYNDAQUIL); @@ -59,8 +59,8 @@ SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type if enemy faints") SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC); ASSUME(gSpeciesInfo[SPECIES_PIKACHU].types[0] == TYPE_ELECTRIC || gSpeciesInfo[SPECIES_PIKACHU].types[1] == TYPE_ELECTRIC); PLAYER(SPECIES_PIKACHU); @@ -79,8 +79,8 @@ SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type") SINGLE_BATTLE_TEST("Double Shock fails if the user isn't an Electric-type") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("Double Shock fails if the user isn't an Electric-type") SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type if enemy faints") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); + ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC); ASSUME(gSpeciesInfo[SPECIES_PIKACHU].types[0] == TYPE_ELECTRIC || gSpeciesInfo[SPECIES_PIKACHU].types[1] == TYPE_ELECTRIC); PLAYER(SPECIES_PIKACHU); diff --git a/test/battle/move_effect/fickle_beam.c b/test/battle/move_effect/fickle_beam.c index ffbbe4d18d..0313823aa9 100644 --- a/test/battle/move_effect/fickle_beam.c +++ b/test/battle/move_effect/fickle_beam.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FICKLE_BEAM].effect == EFFECT_FICKLE_BEAM); + ASSUME(GetMoveEffect(MOVE_FICKLE_BEAM) == EFFECT_FICKLE_BEAM); } SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time") @@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time") PASSES_RANDOMLY(30, 100, RNG_FICKLE_BEAM); GIVEN { - ASSUME(gMovesInfo[MOVE_POWER_GEM].power == 80); - ASSUME(gMovesInfo[MOVE_FICKLE_BEAM].power == 80); + ASSUME(GetMovePower(MOVE_POWER_GEM) == 80); + ASSUME(GetMovePower(MOVE_FICKLE_BEAM) == 80); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/fillet_away.c b/test/battle/move_effect/fillet_away.c index de203dbc5a..f9b679bfe5 100644 --- a/test/battle/move_effect/fillet_away.c +++ b/test/battle/move_effect/fillet_away.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FILLET_AWAY].effect == EFFECT_FILLET_AWAY); + ASSUME(GetMoveEffect(MOVE_FILLET_AWAY) == EFFECT_FILLET_AWAY); } SINGLE_BATTLE_TEST("Fillet Away cuts the user's HP in half") diff --git a/test/battle/move_effect/fixed_damage_arg.c b/test/battle/move_effect/fixed_damage_arg.c index 484601be05..8cb2987072 100644 --- a/test/battle/move_effect/fixed_damage_arg.c +++ b/test/battle/move_effect/fixed_damage_arg.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SONIC_BOOM].effect == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveEffect(MOVE_SONIC_BOOM) == EFFECT_FIXED_DAMAGE_ARG); } SINGLE_BATTLE_TEST("Sonic Boom deals fixed damage", s16 damage) @@ -11,9 +11,9 @@ SINGLE_BATTLE_TEST("Sonic Boom deals fixed damage", s16 damage) u16 mon; PARAMETRIZE { mon = SPECIES_RATTATA; } PARAMETRIZE { mon = SPECIES_ARON; } - + GIVEN { - ASSUME(gMovesInfo[MOVE_SONIC_BOOM].argument == 20); + ASSUME(GetMoveFixedDamage(MOVE_SONIC_BOOM) == 20); PLAYER(SPECIES_WOBBUFFET); OPPONENT(mon); } WHEN { diff --git a/test/battle/move_effect/flame_burst.c b/test/battle/move_effect/flame_burst.c index 3597c80014..df0199e116 100644 --- a/test/battle/move_effect/flame_burst.c +++ b/test/battle/move_effect/flame_burst.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FLAME_BURST].additionalEffects->moveEffect == MOVE_EFFECT_FLAME_BURST); + ASSUME(GetMoveAdditionalEffectById(MOVE_FLAME_BURST, 0)->moveEffect == MOVE_EFFECT_FLAME_BURST); } // Flame Burst AoE is supposed to hit through Substitute DOUBLE_BATTLE_TEST("Flame Burst Substitute") { GIVEN { - ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE); + ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/move_effect/fling.c b/test/battle/move_effect/fling.c index 2bd1e824f1..b98020474b 100644 --- a/test/battle/move_effect/fling.c +++ b/test/battle/move_effect/fling.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); } SINGLE_BATTLE_TEST("Fling fails if pokemon holds no item") @@ -38,8 +38,8 @@ SINGLE_BATTLE_TEST("Fling fails if pokemon is under the effects of Embargo or Ma PARAMETRIZE {move = MOVE_MAGIC_ROOM; } GIVEN { - ASSUME(gMovesInfo[MOVE_EMBARGO].effect == EFFECT_EMBARGO); - ASSUME(gMovesInfo[MOVE_MAGIC_ROOM].effect == EFFECT_MAGIC_ROOM); + ASSUME(GetMoveEffect(MOVE_EMBARGO) == EFFECT_EMBARGO); + ASSUME(GetMoveEffect(MOVE_MAGIC_ROOM) == EFFECT_MAGIC_ROOM); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RAZOR_CLAW); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Fling fails for pokemon with Klutz ability") SINGLE_BATTLE_TEST("Fling's thrown item can be regained with Recycle") { GIVEN { - ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE); + ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE); PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -106,7 +106,7 @@ SINGLE_BATTLE_TEST("Fling's thrown item can be regained with Recycle") SINGLE_BATTLE_TEST("Fling - Item is lost even when there is no target") { GIVEN { - ASSUME(gMovesInfo[MOVE_SELF_DESTRUCT].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_SELF_DESTRUCT) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); Speed(2); } OPPONENT(SPECIES_WOBBUFFET) {Speed(5); } OPPONENT(SPECIES_WOBBUFFET) {Speed(5); } @@ -131,7 +131,7 @@ SINGLE_BATTLE_TEST("Fling - Item is lost even when there is no target") SINGLE_BATTLE_TEST("Fling - Item is lost when target protects itself") { GIVEN { - ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT); PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -362,7 +362,7 @@ SINGLE_BATTLE_TEST("Fling - thrown berry's effect activates for the target even PARAMETRIZE { item = ITEM_SALAC_BERRY; effect = HOLD_EFFECT_SPEED_UP; statId = STAT_SPEED; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLING].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_FLING) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Item(item); Attack(1); } OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); HP(399); MaxHP(400); MovesWithPP({MOVE_CELEBRATE, 35}); } } WHEN { @@ -441,7 +441,7 @@ SINGLE_BATTLE_TEST("Fling deals damage based on items fling power") s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_CRUNCH].power == 80); + ASSUME(GetMovePower(MOVE_CRUNCH) == 80); ASSUME(gItemsInfo[ITEM_VENUSAURITE].flingPower == 80); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_VENUSAURITE); } OPPONENT(SPECIES_REGIROCK); diff --git a/test/battle/move_effect/flower_shield.c b/test/battle/move_effect/flower_shield.c index e31fc9e5cd..784cce99f2 100644 --- a/test/battle/move_effect/flower_shield.c +++ b/test/battle/move_effect/flower_shield.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FLOWER_SHIELD].effect == EFFECT_FLOWER_SHIELD); + ASSUME(GetMoveEffect(MOVE_FLOWER_SHIELD) == EFFECT_FLOWER_SHIELD); } DOUBLE_BATTLE_TEST("Flower Shield raises the defense of all grass type pokemon") diff --git a/test/battle/move_effect/focus_punch.c b/test/battle/move_effect/focus_punch.c index e8f36d4ff1..55854ee80e 100644 --- a/test/battle/move_effect/focus_punch.c +++ b/test/battle/move_effect/focus_punch.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH); + ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH); } SINGLE_BATTLE_TEST("Focus Punch activates only if not damaged") diff --git a/test/battle/move_effect/foul_play.c b/test/battle/move_effect/foul_play.c index cc853b48de..7df04201ef 100644 --- a/test/battle/move_effect/foul_play.c +++ b/test/battle/move_effect/foul_play.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FOUL_PLAY].effect == EFFECT_FOUL_PLAY); + ASSUME(GetMoveEffect(MOVE_FOUL_PLAY) == EFFECT_FOUL_PLAY); } SINGLE_BATTLE_TEST("Foul Play uses physical attack stat of target", s16 damage) @@ -14,8 +14,8 @@ SINGLE_BATTLE_TEST("Foul Play uses physical attack stat of target", s16 damage) PARAMETRIZE { move = MOVE_FOUL_PLAY; } GIVEN { - ASSUME(gMovesInfo[MOVE_HIGH_HORSEPOWER].power == gMovesInfo[MOVE_FOUL_PLAY].power); - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMovePower(MOVE_HIGH_HORSEPOWER) == GetMovePower(MOVE_FOUL_PLAY)); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_SHELLDER); OPPONENT(SPECIES_SHELLDER); } WHEN { diff --git a/test/battle/move_effect/fury_cutter.c b/test/battle/move_effect/fury_cutter.c index b193882d37..10d9d8a64e 100644 --- a/test/battle/move_effect/fury_cutter.c +++ b/test/battle/move_effect/fury_cutter.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FURY_CUTTER].effect == EFFECT_FURY_CUTTER); + ASSUME(GetMoveEffect(MOVE_FURY_CUTTER) == EFFECT_FURY_CUTTER); } SINGLE_BATTLE_TEST("Fury Cutter power doubles with each use, up to 160 power") diff --git a/test/battle/move_effect/future_sight.c b/test/battle/move_effect/future_sight.c index e25fc75012..3995e8479f 100644 --- a/test/battle/move_effect/future_sight.c +++ b/test/battle/move_effect/future_sight.c @@ -3,10 +3,10 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SEED_FLARE].power == gMovesInfo[MOVE_FUTURE_SIGHT].power); - ASSUME(gMovesInfo[MOVE_SEED_FLARE].category == gMovesInfo[MOVE_FUTURE_SIGHT].category); - ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].effect == EFFECT_FUTURE_SIGHT); - ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].power > 0); + ASSUME(GetMovePower(MOVE_SEED_FLARE) == GetMovePower(MOVE_FUTURE_SIGHT)); + ASSUME(GetMoveCategory(MOVE_SEED_FLARE) == GetMoveCategory(MOVE_FUTURE_SIGHT)); + ASSUME(GetMoveEffect(MOVE_FUTURE_SIGHT) == EFFECT_FUTURE_SIGHT); + ASSUME(GetMovePower(MOVE_FUTURE_SIGHT) > 0); } SINGLE_BATTLE_TEST("Future Sight uses Sp. Atk stat of the original user without modifiers") @@ -159,7 +159,7 @@ SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints by residual d SINGLE_BATTLE_TEST("Future Sight breaks Focus Sash and doesn't make the holder endure another move") { GIVEN { - ASSUME(gMovesInfo[MOVE_PSYCHIC].power > 0); + ASSUME(GetMovePower(MOVE_PSYCHIC) > 0); ASSUME(gItemsInfo[ITEM_FOCUS_SASH].holdEffect == HOLD_EFFECT_FOCUS_SASH); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_PIDGEY) { Level(1); Item(ITEM_FOCUS_SASH); } diff --git a/test/battle/move_effect/gastro_acid.c b/test/battle/move_effect/gastro_acid.c index b3ce378794..8cb0a7d4af 100644 --- a/test/battle/move_effect/gastro_acid.c +++ b/test/battle/move_effect/gastro_acid.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID); + ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID); } SINGLE_BATTLE_TEST("Gastro Acid fails if target has a banned ability") diff --git a/test/battle/move_effect/glaive_rush.c b/test/battle/move_effect/glaive_rush.c index 639756da44..bb5bb7aaf6 100644 --- a/test/battle/move_effect/glaive_rush.c +++ b/test/battle/move_effect/glaive_rush.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GLAIVE_RUSH].effect == EFFECT_GLAIVE_RUSH); + ASSUME(GetMoveEffect(MOVE_GLAIVE_RUSH) == EFFECT_GLAIVE_RUSH); } SINGLE_BATTLE_TEST("If Glaive Rush is successful moves targeted at the user do not check accuracy") { PASSES_RANDOMLY(100, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_MEGA_PUNCH].accuracy == 85); + ASSUME(GetMoveAccuracy(MOVE_MEGA_PUNCH) == 85); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/terrain/grassy.c b/test/battle/move_effect/grassy_terrain.c similarity index 80% rename from test/battle/terrain/grassy.c rename to test/battle/move_effect/grassy_terrain.c index b247933dd2..90e878b6dd 100644 --- a/test/battle/terrain/grassy.c +++ b/test/battle/move_effect/grassy_terrain.c @@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Grassy Terrain recovers 1/16th HP at end of turn") } } -SINGLE_BATTLE_TEST("Grassy Terrain activates Grassy Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_GRASSY_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Grass!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GRASS); - } -} - SINGLE_BATTLE_TEST("Grassy Terrain increases power of Grass-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/gravity.c b/test/battle/move_effect/gravity.c index 4ccad08b58..baac7a53ea 100644 --- a/test/battle/move_effect/gravity.c +++ b/test/battle/move_effect/gravity.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GRAVITY].effect == EFFECT_GRAVITY); + ASSUME(GetMoveEffect(MOVE_GRAVITY) == EFFECT_GRAVITY); } DOUBLE_BATTLE_TEST("Gravity cancels fly and sky drop if they are in the air") diff --git a/test/battle/move_effect/guard_split.c b/test/battle/move_effect/guard_split.c index 3f012ab6e2..d7572c1431 100644 --- a/test/battle/move_effect/guard_split.c +++ b/test/battle/move_effect/guard_split.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GUARD_SPLIT].effect == EFFECT_GUARD_SPLIT); + ASSUME(GetMoveEffect(MOVE_GUARD_SPLIT) == EFFECT_GUARD_SPLIT); } SINGLE_BATTLE_TEST("Guard Split averages users and targets Def and Sp. Def stats") diff --git a/test/battle/move_effect/haze.c b/test/battle/move_effect/haze.c index 0b28268ae9..3d0602bb73 100644 --- a/test/battle/move_effect/haze.c +++ b/test/battle/move_effect/haze.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HAZE].effect == EFFECT_HAZE); + ASSUME(GetMoveEffect(MOVE_HAZE) == EFFECT_HAZE); } SINGLE_BATTLE_TEST("Haze resets stat changes", s16 damage) @@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Haze resets stat changes", s16 damage) PARAMETRIZE { haze = FALSE; } PARAMETRIZE { haze = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_MEDITATE].effect == EFFECT_ATTACK_UP); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveEffect(MOVE_MEDITATE) == EFFECT_ATTACK_UP); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c index 9b62a36f9b..5c87171056 100644 --- a/test/battle/move_effect/heal_bell.c +++ b/test/battle/move_effect/heal_bell.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); - ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); } DOUBLE_BATTLE_TEST("Heal Bell cures the entire party") diff --git a/test/battle/move_effect/heal_pulse.c b/test/battle/move_effect/heal_pulse.c index e252039982..7c46cbf344 100644 --- a/test/battle/move_effect/heal_pulse.c +++ b/test/battle/move_effect/heal_pulse.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HEAL_PULSE].effect == EFFECT_HEAL_PULSE); + ASSUME(GetMoveEffect(MOVE_HEAL_PULSE) == EFFECT_HEAL_PULSE); } SINGLE_BATTLE_TEST("Heal Pulse heals the target by 1/2 of it's maxHP") @@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Heal Pulse ignores accurace checks") SINGLE_BATTLE_TEST("Heal Pulse is blocked by Substitute") { GIVEN { - ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE); + ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE); PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(50); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -86,8 +86,8 @@ SINGLE_BATTLE_TEST("Heal Pulse is blocked by Substitute") SINGLE_BATTLE_TEST("Floral Healing heals the target by 2/3rd of it's maxHP if Grassy Terrain is on the field") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLORAL_HEALING].argument == MOVE_EFFECT_FLORAL_HEALING); - ASSUME(gMovesInfo[MOVE_GRASSY_TERRAIN].effect == EFFECT_GRASSY_TERRAIN); + ASSUME(GetMoveEffectArg_MoveProperty(MOVE_FLORAL_HEALING) == MOVE_EFFECT_FLORAL_HEALING); + ASSUME(GetMoveEffect(MOVE_GRASSY_TERRAIN) == EFFECT_GRASSY_TERRAIN); PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(1); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/healing_wish.c b/test/battle/move_effect/healing_wish.c index a597d552ed..a29b04367c 100644 --- a/test/battle/move_effect/healing_wish.c +++ b/test/battle/move_effect/healing_wish.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH); - ASSUME(gMovesInfo[MOVE_LUNAR_DANCE].effect == EFFECT_HEALING_WISH); + ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH); + ASSUME(GetMoveEffect(MOVE_LUNAR_DANCE) == EFFECT_HEALING_WISH); } SINGLE_BATTLE_TEST("Healing Wish causes the user to faint and fully heals the replacement") diff --git a/test/battle/move_effect/hit_escape.c b/test/battle/move_effect/hit_escape.c index 0a494cc667..bdfdbcae98 100644 --- a/test/battle/move_effect/hit_escape.c +++ b/test/battle/move_effect/hit_escape.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); } SINGLE_BATTLE_TEST("U-turn switches the user out") @@ -98,7 +98,7 @@ SINGLE_BATTLE_TEST("U-turn switches the user out if Wimp Out fails to activate") SINGLE_BATTLE_TEST("U-turn switches the user out after Ice Face activates") { GIVEN { - ASSUME(gMovesInfo[MOVE_U_TURN].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_U_TURN) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_BEEDRILL); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_EISCUE) { Ability(ABILITY_ICE_FACE); } diff --git a/test/battle/move_effect/hit_set_remove_terrain.c b/test/battle/move_effect/hit_set_remove_terrain.c index a48d316d3f..9b9180d6e4 100644 --- a/test/battle/move_effect/hit_set_remove_terrain.c +++ b/test/battle/move_effect/hit_set_remove_terrain.c @@ -3,12 +3,12 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ELECTRIC_TERRAIN].effect == EFFECT_ELECTRIC_TERRAIN); - ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN); - ASSUME(gMovesInfo[MOVE_GRASSY_TERRAIN].effect == EFFECT_GRASSY_TERRAIN); - ASSUME(gMovesInfo[MOVE_MISTY_TERRAIN].effect == EFFECT_MISTY_TERRAIN); - ASSUME(gMovesInfo[MOVE_STEEL_ROLLER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); - ASSUME(gMovesInfo[MOVE_ICE_SPINNER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); + ASSUME(GetMoveEffect(MOVE_ELECTRIC_TERRAIN) == EFFECT_ELECTRIC_TERRAIN); + ASSUME(GetMoveEffect(MOVE_PSYCHIC_TERRAIN) == EFFECT_PSYCHIC_TERRAIN); + ASSUME(GetMoveEffect(MOVE_GRASSY_TERRAIN) == EFFECT_GRASSY_TERRAIN); + ASSUME(GetMoveEffect(MOVE_MISTY_TERRAIN) == EFFECT_MISTY_TERRAIN); + ASSUME(GetMoveEffect(MOVE_STEEL_ROLLER) == EFFECT_HIT_SET_REMOVE_TERRAIN); + ASSUME(GetMoveEffect(MOVE_ICE_SPINNER) == EFFECT_HIT_SET_REMOVE_TERRAIN); } SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner can remove a terrain from the field") @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Ice Spinner doesn't fail if there is no terrain on the field } } -AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fail") +AI_SINGLE_BATTLE_TEST("AI will not choose Steel Roller if it might fail") { u32 move; @@ -104,7 +104,7 @@ AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fai } } -AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there is a terrain or not") +AI_SINGLE_BATTLE_TEST("AI will can choose Ice Spinner regardless if there is a terrain or not") { u32 move; @@ -124,35 +124,3 @@ AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there i } } } - -SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner reverts typing on Mimicry users") -{ - u32 j; - static const u16 terrainMoves[] = - { - MOVE_ELECTRIC_TERRAIN, - MOVE_PSYCHIC_TERRAIN, - MOVE_GRASSY_TERRAIN, - MOVE_MISTY_TERRAIN, - }; - - u16 terrainMove = MOVE_NONE; - u16 removeTerrainMove = MOVE_NONE; - - for (j = 0; j < ARRAY_COUNT(terrainMoves); j++) - { - PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainMoves[j]; } - PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainMoves[j]; } - } - - GIVEN { - ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } - TURN { MOVE(player, MOVE_TOXIC); } - } SCENE { - MESSAGE("It doesn't affect the opposing Stunfisk…"); - } -} diff --git a/test/battle/move_effect/hit_switch_target.c b/test/battle/move_effect/hit_switch_target.c index a899ae0b33..5a6e480f93 100644 --- a/test/battle/move_effect/hit_switch_target.c +++ b/test/battle/move_effect/hit_switch_target.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); - ASSUME(gMovesInfo[MOVE_LOCK_ON].effect == EFFECT_LOCK_ON); + ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET); + ASSUME(GetMoveEffect(MOVE_LOCK_ON) == EFFECT_LOCK_ON); } SINGLE_BATTLE_TEST("Dragon Tail switches the target with a random non-fainted replacement") diff --git a/test/battle/move_effect/hold_hands.c b/test/battle/move_effect/hold_hands.c index bcdb6a952a..fb1c498bd3 100644 --- a/test/battle/move_effect/hold_hands.c +++ b/test/battle/move_effect/hold_hands.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HOLD_HANDS].effect == EFFECT_HOLD_HANDS); + ASSUME(GetMoveEffect(MOVE_HOLD_HANDS) == EFFECT_HOLD_HANDS); } DOUBLE_BATTLE_TEST("Hold Hands is blocked by Crafty Shield") diff --git a/test/battle/move_effect/hydro_steam.c b/test/battle/move_effect/hydro_steam.c index a9c14c9acb..cb19cc6ec1 100644 --- a/test/battle/move_effect/hydro_steam.c +++ b/test/battle/move_effect/hydro_steam.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HYDRO_STEAM].effect == EFFECT_HYDRO_STEAM); + ASSUME(GetMoveEffect(MOVE_HYDRO_STEAM) == EFFECT_HYDRO_STEAM); } SINGLE_BATTLE_TEST("Hydro Steam deals 1.5x damage under both Sunlight and Rain", s16 damage) diff --git a/test/battle/move_effect/instruct.c b/test/battle/move_effect/instruct.c index 59772ea944..248370cd6a 100644 --- a/test/battle/move_effect/instruct.c +++ b/test/battle/move_effect/instruct.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT); + ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT); } DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move") @@ -24,7 +24,7 @@ DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move") DOUBLE_BATTLE_TEST("Instruct fails if move is banned by Instruct") { GIVEN { - ASSUME(gMovesInfo[MOVE_BIDE].instructBanned == TRUE); + ASSUME(IsMoveInstructBanned(MOVE_BIDE)); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_BIDE); } OPPONENT(SPECIES_WOBBUFFET); @@ -60,7 +60,7 @@ DOUBLE_BATTLE_TEST("Instruct-called move targets the target of the move picked o DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); } OPPONENT(SPECIES_WOBBUFFET); @@ -79,7 +79,7 @@ DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep") DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE); + ASSUME(IsDanceMove(MOVE_DRAGON_DANCE)); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_ORICORIO) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_CELEBRATE); } OPPONENT(SPECIES_WOBBUFFET); @@ -100,7 +100,7 @@ DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used" DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the first turn but consumes PP") { GIVEN { - ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY); + ASSUME(GetMoveEffect(MOVE_FAKE_OUT) == EFFECT_FIRST_TURN_ONLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); } OPPONENT(SPECIES_WOBBUFFET); @@ -112,14 +112,14 @@ DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the fir ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft); NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, playerRight); } THEN { - EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_FAKE_OUT].pp - 2); + EXPECT_EQ(playerRight->pp[3], GetMovePP(MOVE_FAKE_OUT) - 2); } } DOUBLE_BATTLE_TEST("Instruct-called move doesn't fail if tormented") { GIVEN { - ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT); + ASSUME(GetMoveEffect(MOVE_TORMENT) == EFFECT_TORMENT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); } OPPONENT(SPECIES_WOBBUFFET); @@ -138,7 +138,7 @@ DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault V { GIVEN { ASSUME(gItemsInfo[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST); - ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_TRICK); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ASSAULT_VEST); } @@ -155,7 +155,7 @@ DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault V DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted") { GIVEN { - ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT); + ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); } OPPONENT(SPECIES_WOBBUFFET); @@ -174,14 +174,14 @@ DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted") ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); } } THEN { - EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_GROWL].pp - 1); + EXPECT_EQ(playerRight->pp[3], GetMovePP(MOVE_GROWL) - 1); } } DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled") { GIVEN { - ASSUME(gMovesInfo[MOVE_DISABLE].effect == EFFECT_DISABLE); + ASSUME(GetMoveEffect(MOVE_DISABLE) == EFFECT_DISABLE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); } OPPONENT(SPECIES_WOBBUFFET); @@ -194,15 +194,15 @@ DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled") ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft); NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); } THEN { - EXPECT_EQ(playerRight->pp[0], gMovesInfo[MOVE_TACKLE].pp - 1); + EXPECT_EQ(playerRight->pp[0], GetMovePP(MOVE_TACKLE) - 1); } } DOUBLE_BATTLE_TEST("Instruct-called moves keep their priority") { GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); - ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); + ASSUME(GetMoveEffect(MOVE_PSYCHIC_TERRAIN) == EFFECT_PSYCHIC_TERRAIN); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_QUICK_ATTACK); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/ion_deluge.c b/test/battle/move_effect/ion_deluge.c index d0862ee8b4..8147048527 100644 --- a/test/battle/move_effect/ion_deluge.c +++ b/test/battle/move_effect/ion_deluge.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE); + ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE); } // For some reason SINGLE_BATTLE_TEST didn't catch these two issues. @@ -51,7 +51,7 @@ WILD_BATTLE_TEST("Ion Deluge works the same way as always when used by a mon wit SINGLE_BATTLE_TEST("Ion Deluge makes Normal type moves Electric type") { GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GOLBAT); } WHEN { diff --git a/test/battle/move_effect/ivy_cudgel.c b/test/battle/move_effect/ivy_cudgel.c index 095f4d8eff..88d002ae35 100644 --- a/test/battle/move_effect/ivy_cudgel.c +++ b/test/battle/move_effect/ivy_cudgel.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_IVY_CUDGEL].effect == EFFECT_IVY_CUDGEL); + ASSUME(GetMoveEffect(MOVE_IVY_CUDGEL) == EFFECT_IVY_CUDGEL); } SINGLE_BATTLE_TEST("Ivy Cudgel changes the move type depending on the form of Ogerpon") diff --git a/test/battle/move_effect/knock_off.c b/test/battle/move_effect/knock_off.c index 61bb062a25..4eb1269717 100644 --- a/test/battle/move_effect/knock_off.c +++ b/test/battle/move_effect/knock_off.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF); + ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF); } SINGLE_BATTLE_TEST("Knock Off knocks a healing berry before it has the chance to activate") diff --git a/test/battle/move_effect/last_resort.c b/test/battle/move_effect/last_resort.c index a9660f2c0e..50a0a31512 100644 --- a/test/battle/move_effect/last_resort.c +++ b/test/battle/move_effect/last_resort.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_LAST_RESORT].effect == EFFECT_LAST_RESORT); + ASSUME(GetMoveEffect(MOVE_LAST_RESORT) == EFFECT_LAST_RESORT); } SINGLE_BATTLE_TEST("Last Resort always fails if it's the only known move") @@ -95,7 +95,7 @@ SINGLE_BATTLE_TEST("Last Resort works only when all of the known moves have been SINGLE_BATTLE_TEST("Last Resort works with Sleep Talk") { GIVEN { - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/last_respects.c b/test/battle/move_effect/last_respects.c index 9b1f01f5fc..6ef4c73c2d 100644 --- a/test/battle/move_effect/last_respects.c +++ b/test/battle/move_effect/last_respects.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_LAST_RESPECTS].effect == EFFECT_LAST_RESPECTS); + ASSUME(GetMoveEffect(MOVE_LAST_RESPECTS) == EFFECT_LAST_RESPECTS); } SINGLE_BATTLE_TEST("Last Respects power is multiplied by the amount of fainted mon in the user's side - Player", s16 damage) diff --git a/test/battle/move_effect/leech_seed.c b/test/battle/move_effect/leech_seed.c index 67e829cf8a..d363e98009 100644 --- a/test/battle/move_effect/leech_seed.c +++ b/test/battle/move_effect/leech_seed.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED); + ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED); } SINGLE_BATTLE_TEST("Leech Seed doesn't affect Grass-type Pokémon") @@ -58,25 +58,6 @@ SINGLE_BATTLE_TEST("Leech Seed recovery is prevented by Heal Block") } } -SINGLE_BATTLE_TEST("Leech Seed recovery will drain the hp of user if leech seeded mon has Liquid Ooze") -{ - s16 damage; - s16 healed; - - GIVEN { - PLAYER(SPECIES_WYNAUT); - OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } - } WHEN { - TURN { MOVE(player, MOVE_LEECH_SEED); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); - HP_BAR(opponent, captureDamage: &damage); - HP_BAR(player, captureDamage: &healed); - } THEN { - EXPECT_EQ(damage, healed); - } -} - TO_DO_BATTLE_TEST("Leech Seed doesn't affect already seeded targets") TO_DO_BATTLE_TEST("Leech Seed's effect is paused until a new battler replaces the original user's position") // Faint, can't be replaced, then revived. TO_DO_BATTLE_TEST("Leech Seed's effect pause still prevents it from being seeded again") diff --git a/test/battle/move_effect/magic_coat.c b/test/battle/move_effect/magic_coat.c index 2e78967f39..561d15a532 100644 --- a/test/battle/move_effect/magic_coat.c +++ b/test/battle/move_effect/magic_coat.c @@ -3,13 +3,13 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); } SINGLE_BATTLE_TEST("Magic Coat prints the correct message when bouncing back a move") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_WYNAUT); } WHEN { diff --git a/test/battle/move_effect/max_hp_50_recoil.c b/test/battle/move_effect/max_hp_50_recoil.c index b35043014b..3e54e05532 100644 --- a/test/battle/move_effect/max_hp_50_recoil.c +++ b/test/battle/move_effect/max_hp_50_recoil.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STEEL_BEAM].effect == EFFECT_MAX_HP_50_RECOIL); + ASSUME(GetMoveEffect(MOVE_STEEL_BEAM) == EFFECT_MAX_HP_50_RECOIL); } SINGLE_BATTLE_TEST("Steel Beam makes the user lose 1/2 of its Max HP") diff --git a/test/battle/move_effect/metronome.c b/test/battle/move_effect/metronome.c index 98e4bfd618..1a5d4aeb9d 100644 --- a/test/battle/move_effect/metronome.c +++ b/test/battle/move_effect/metronome.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_METRONOME].effect == EFFECT_METRONOME); + ASSUME(GetMoveEffect(MOVE_METRONOME) == EFFECT_METRONOME); } SINGLE_BATTLE_TEST("Metronome picks a random move") @@ -25,9 +25,9 @@ SINGLE_BATTLE_TEST("Metronome picks a random move") SINGLE_BATTLE_TEST("Metronome's called powder move fails against Grass Types") { GIVEN { - ASSUME(gMovesInfo[MOVE_POISON_POWDER].powderMove); + ASSUME(IsPowderMove(MOVE_POISON_POWDER)); ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_TANGELA); } WHEN { @@ -45,7 +45,7 @@ SINGLE_BATTLE_TEST("Metronome's called powder move fails against Grass Types") SINGLE_BATTLE_TEST("Metronome's called multi-hit move hits multiple times") { GIVEN { - ASSUME(gMovesInfo[MOVE_ROCK_BLAST].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_ROCK_BLAST) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/mind_blown.c b/test/battle/move_effect/mind_blown.c index 85e6a8fdbd..0a34198777 100644 --- a/test/battle/move_effect/mind_blown.c +++ b/test/battle/move_effect/mind_blown.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MIND_BLOWN].effect == EFFECT_MIND_BLOWN); + ASSUME(GetMoveEffect(MOVE_MIND_BLOWN) == EFFECT_MIND_BLOWN); } SINGLE_BATTLE_TEST("Mind Blown makes the user lose 1/2 of its Max HP") @@ -154,7 +154,7 @@ SINGLE_BATTLE_TEST("Mind Blown makes the user lose HP even if the opposing mon p SINGLE_BATTLE_TEST("Mind Blown makes the user lose HP even if it is absorbed by Flash Fire") { GIVEN { - ASSUME(gMovesInfo[MOVE_MIND_BLOWN].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_MIND_BLOWN) == TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_CYNDAQUIL) { Ability(ABILITY_FLASH_FIRE); } } WHEN { diff --git a/test/battle/move_effect/mirror_move.c b/test/battle/move_effect/mirror_move.c index 65c600fb18..cc148eb97c 100644 --- a/test/battle/move_effect/mirror_move.c +++ b/test/battle/move_effect/mirror_move.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].effect == EFFECT_MIRROR_MOVE); + ASSUME(GetMoveEffect(MOVE_MIRROR_MOVE) == EFFECT_MIRROR_MOVE); } SINGLE_BATTLE_TEST("Mirror Move copies the last used move by the target") @@ -41,9 +41,9 @@ SINGLE_BATTLE_TEST("Mirror Move fails if no move was used before") SINGLE_BATTLE_TEST("Mirror Move's called powder move fails against Grass Types") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); - ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE); + ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE); PLAYER(SPECIES_ODDISH); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -62,7 +62,7 @@ SINGLE_BATTLE_TEST("Mirror Move's called powder move fails against Grass Types") SINGLE_BATTLE_TEST("Mirror Move's called multi-hit move hits multiple times") { GIVEN { - ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/terrain/misty.c b/test/battle/move_effect/misty_terrain.c similarity index 78% rename from test/battle/terrain/misty.c rename to test/battle/move_effect/misty_terrain.c index e43cf4a253..b96f0c650d 100644 --- a/test/battle/terrain/misty.c +++ b/test/battle/move_effect/misty_terrain.c @@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Misty Terrain protects grounded battlers from non-volatile s } } -SINGLE_BATTLE_TEST("Misty Terrain activates Misty Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_MISTY_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Fairy!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_FAIRY); - } -} - SINGLE_BATTLE_TEST("Misty Terrain does not increase the power of Fairy-type moves", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/moonlight.c b/test/battle/move_effect/moonlight.c index 41359ea97c..34baa31b14 100644 --- a/test/battle/move_effect/moonlight.c +++ b/test/battle/move_effect/moonlight.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MOONLIGHT].effect == EFFECT_MOONLIGHT); + ASSUME(GetMoveEffect(MOVE_MOONLIGHT) == EFFECT_MOONLIGHT); } SINGLE_BATTLE_TEST("Moonlight recovers 1/2 of the user's max HP") diff --git a/test/battle/move_effect/morning_sun.c b/test/battle/move_effect/morning_sun.c index 3b57f89500..64fb1b044b 100644 --- a/test/battle/move_effect/morning_sun.c +++ b/test/battle/move_effect/morning_sun.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_MORNING_SUN].effect == EFFECT_MORNING_SUN); + ASSUME(GetMoveEffect(MOVE_MORNING_SUN) == EFFECT_MORNING_SUN); } SINGLE_BATTLE_TEST("Morning Sun recovers 1/2 of the user's max HP") diff --git a/test/battle/move_effect/multi_hit.c b/test/battle/move_effect/multi_hit.c index e2331efbf7..da96c07c90 100644 --- a/test/battle/move_effect/multi_hit.c +++ b/test/battle/move_effect/multi_hit.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT); } SINGLE_BATTLE_TEST("Multi hit Moves hit the maximum amount with Skill Link") @@ -141,7 +141,7 @@ SINGLE_BATTLE_TEST("Multi hit Moves hit five times 50 Percent of the time with L SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after final hit") { GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -163,8 +163,8 @@ SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after final SINGLE_BATTLE_TEST("Scale Shot is immune to Fairy types and will end the move correctly") { GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].type == TYPE_DRAGON); + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); + ASSUME(GetMoveType(MOVE_SCALE_SHOT) == TYPE_DRAGON); ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_CLEFAIRY) { HP(1); } @@ -179,7 +179,7 @@ SINGLE_BATTLE_TEST("Scale Shot is immune to Fairy types and will end the move co DOUBLE_BATTLE_TEST("Scale Shot does not corrupt the next turn move used") { GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -200,35 +200,11 @@ DOUBLE_BATTLE_TEST("Scale Shot does not corrupt the next turn move used") } } -SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); - ASSUME(gMovesInfo[MOVE_ENDURE].effect == EFFECT_ENDURE); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { HP(1); } - } WHEN { - TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - MESSAGE("The Pokémon was hit 5 time(s)!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's Defense fell!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's Speed rose!"); - } -} - SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after the 4th hit of Loaded Dice") { PASSES_RANDOMLY(50, 100, RNG_LOADED_DICE); GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LOADED_DICE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -253,7 +229,7 @@ SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after killi PARAMETRIZE { item = ITEM_LOADED_DICE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT); PLAYER(SPECIES_BAGON) { Item(item); } OPPONENT(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/ohko.c b/test/battle/move_effect/ohko.c index 8a8015309b..11dbb78f1f 100644 --- a/test/battle/move_effect/ohko.c +++ b/test/battle/move_effect/ohko.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SHEER_COLD].effect == EFFECT_OHKO); + ASSUME(GetMoveEffect(MOVE_SHEER_COLD) == EFFECT_OHKO); } SINGLE_BATTLE_TEST("Sheer Cold doesn't affect Ice-type Pokémon") @@ -24,7 +24,7 @@ SINGLE_BATTLE_TEST("Sheer Cold doesn't affect Ice-type Pokémon") SINGLE_BATTLE_TEST("OHKO moves can hit semi-invulnerable mons when the user has No-Guard") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHEER_COLD].effect == EFFECT_OHKO); + ASSUME(GetMoveEffect(MOVE_SHEER_COLD) == EFFECT_OHKO); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_NO_GUARD); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/photon_geyser.c b/test/battle/move_effect/photon_geyser.c index 986d3865aa..3f4bb10146 100644 --- a/test/battle/move_effect/photon_geyser.c +++ b/test/battle/move_effect/photon_geyser.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].effect == EFFECT_PHOTON_GEYSER); + ASSUME(GetMoveEffect(MOVE_PHOTON_GEYSER) == EFFECT_PHOTON_GEYSER); } SINGLE_BATTLE_TEST("Photon Geyser can be mirror coated if it is a special move") { GIVEN { // EFFECT_PHOTON_GEYSER requires the move data to be Special to work - ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_PHOTON_GEYSER) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET) { Attack(100); SpAttack(110); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/pledge.c b/test/battle/move_effect/pledge.c index 726adc8152..5a659d7b96 100644 --- a/test/battle/move_effect/pledge.c +++ b/test/battle/move_effect/pledge.c @@ -3,9 +3,9 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WATER_PLEDGE].effect == EFFECT_PLEDGE); - ASSUME(gMovesInfo[MOVE_FIRE_PLEDGE].effect == EFFECT_PLEDGE); - ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].effect == EFFECT_PLEDGE); + ASSUME(GetMoveEffect(MOVE_WATER_PLEDGE) == EFFECT_PLEDGE); + ASSUME(GetMoveEffect(MOVE_FIRE_PLEDGE) == EFFECT_PLEDGE); + ASSUME(GetMoveEffect(MOVE_GRASS_PLEDGE) == EFFECT_PLEDGE); } DOUBLE_BATTLE_TEST("Water and Fire Pledge create a rainbow on the user's side of the field for four turns") @@ -189,7 +189,7 @@ DOUBLE_BATTLE_TEST("The base power of a combined pledge move effect is 150") s16 combinedPledgeDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_BEAM].power == 150); + ASSUME(GetMovePower(MOVE_HYPER_BEAM) == 150); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WYNAUT) { Speed(3); } OPPONENT(SPECIES_WOBBUFFET) { Speed(8); } @@ -313,7 +313,7 @@ DOUBLE_BATTLE_TEST("Damage calculation: Combined pledge move") PARAMETRIZE { expectedDamage = 136; } PARAMETRIZE { expectedDamage = 135; } GIVEN { - ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_GRASS_PLEDGE) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WOBBUFFET) { HP(521); SpDefense(152); Speed(3); } OPPONENT(SPECIES_CHARIZARD) { Speed(8); } @@ -344,7 +344,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo interactions with Powder are correct") PARAMETRIZE { moveLeft = MOVE_GRASS_PLEDGE; moveRight = MOVE_FIRE_PLEDGE; speedLeft = 4; speedRight = 3; } PARAMETRIZE { moveLeft = MOVE_GRASS_PLEDGE; moveRight = MOVE_FIRE_PLEDGE; speedLeft = 3; speedRight = 4; } // FAIL 2 GIVEN { - ASSUME(gMovesInfo[MOVE_FIRE_PLEDGE].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_FIRE_PLEDGE) == TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET) { Speed(speedLeft); } PLAYER(SPECIES_WYNAUT) { Speed(speedRight); } OPPONENT(SPECIES_WOBBUFFET) { Speed(8); } @@ -885,7 +885,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Electrify") { GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_MAROWAK) { Ability(ABILITY_LIGHTNING_ROD); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1002,7 +1002,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Motor Drive") { GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1027,7 +1027,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Volt Absorb") { GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/population_bomb.c b/test/battle/move_effect/population_bomb.c index b3e2e4768e..54da0726ae 100644 --- a/test/battle/move_effect/population_bomb.c +++ b/test/battle/move_effect/population_bomb.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Population Bomb can hit ten times") { GIVEN { - ASSUME(gMovesInfo[MOVE_POPULATION_BOMB].strikeCount == 10); + ASSUME(GetMoveStrikeCount(MOVE_POPULATION_BOMB) == 10); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/powder.c b/test/battle/move_effect/powder.c index 85e486918b..aa789fb05f 100644 --- a/test/battle/move_effect/powder.c +++ b/test/battle/move_effect/powder.c @@ -3,9 +3,9 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_POWDER].effect == EFFECT_POWDER); - ASSUME(gMovesInfo[MOVE_POWDER].powderMove == TRUE); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveEffect(MOVE_POWDER) == EFFECT_POWDER); + ASSUME(IsPowderMove(MOVE_POWDER)); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); } @@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Powder blocks the target's Fire type moves and consumes PP") HP_BAR(opponent); } } THEN { - EXPECT_EQ(player->pp[0], gMovesInfo[MOVE_EMBER].pp - 1); + EXPECT_EQ(player->pp[0], GetMovePP(MOVE_EMBER) - 1); } } @@ -164,8 +164,8 @@ SINGLE_BATTLE_TEST("Powder fails if the target has Overcoat") DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it was given Grass type") { GIVEN { - ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE); - ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS); + ASSUME(GetMoveEffect(MOVE_FORESTS_CURSE) == EFFECT_THIRD_TYPE); + ASSUME(GetMoveArgType(MOVE_FORESTS_CURSE) == TYPE_GRASS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_TREVENANT); @@ -185,7 +185,7 @@ DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it was given Overcoat") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOODLE].effect == EFFECT_DOODLE); + ASSUME(GetMoveEffect(MOVE_DOODLE) == EFFECT_DOODLE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_FORRETRESS) { Ability(ABILITY_OVERCOAT); } @@ -224,8 +224,8 @@ SINGLE_BATTLE_TEST("Powder prevents Protean from changing its user to Fire type" SINGLE_BATTLE_TEST("Powder doesn't prevent a Fire move from thawing its user out") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].thawsUser); - ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].type == TYPE_FIRE); + ASSUME(MoveThawsUser(MOVE_FLAME_WHEEL)); + ASSUME(GetMoveType(MOVE_FLAME_WHEEL) == TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); } OPPONENT(SPECIES_VIVILLON); } WHEN { @@ -244,7 +244,7 @@ SINGLE_BATTLE_TEST("Powder doesn't prevent a Fire move from thawing its user out SINGLE_BATTLE_TEST("Powder doesn't consume Berry from Fire type Natural Gift but prevents using the move") { GIVEN { - ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); + ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHERI_BERRY); } OPPONENT(SPECIES_VIVILLON); } WHEN { @@ -267,12 +267,12 @@ DOUBLE_BATTLE_TEST("Powder damages a target using Shell Trap even if it wasn't h PARAMETRIZE { move = MOVE_EMBER; } PARAMETRIZE { move = MOVE_TICKLE;} GIVEN { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].effect == EFFECT_SHELL_TRAP); - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_TICKLE].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_TICKLE].effect == EFFECT_TICKLE); + ASSUME(GetMoveEffect(MOVE_SHELL_TRAP) == EFFECT_SHELL_TRAP); + ASSUME(GetMoveType(MOVE_SHELL_TRAP) == TYPE_FIRE); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_EMBER) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TICKLE) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_TICKLE) == EFFECT_TICKLE); PLAYER(SPECIES_TURTONATOR); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/move_effect/power_based_on_target_hp.c b/test/battle/move_effect/power_based_on_target_hp.c index 2cecf3ff7f..030418cd87 100644 --- a/test/battle/move_effect/power_based_on_target_hp.c +++ b/test/battle/move_effect/power_based_on_target_hp.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_POWER_BASED_ON_TARGET_HP); + ASSUME(GetMoveEffect(MOVE_CRUSH_GRIP) == EFFECT_POWER_BASED_ON_TARGET_HP); } SINGLE_BATTLE_TEST("Crush Grip's damage is affected by the target's current HP", s16 damage) diff --git a/test/battle/move_effect/power_based_on_user_hp.c b/test/battle/move_effect/power_based_on_user_hp.c index 1dfa70ddf9..622b195525 100644 --- a/test/battle/move_effect/power_based_on_user_hp.c +++ b/test/battle/move_effect/power_based_on_user_hp.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ERUPTION].effect == EFFECT_POWER_BASED_ON_USER_HP); + ASSUME(GetMoveEffect(MOVE_ERUPTION) == EFFECT_POWER_BASED_ON_USER_HP); } SINGLE_BATTLE_TEST("Eruption's damage is affected by the user's current HP", s16 damage) diff --git a/test/battle/move_effect/power_split.c b/test/battle/move_effect/power_split.c index 70d1bfd5ea..84c64b1d89 100644 --- a/test/battle/move_effect/power_split.c +++ b/test/battle/move_effect/power_split.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_POWER_SPLIT].effect == EFFECT_POWER_SPLIT); + ASSUME(GetMoveEffect(MOVE_POWER_SPLIT) == EFFECT_POWER_SPLIT); } SINGLE_BATTLE_TEST("Power Split averages user and targets Atk and Sp. Atk stats") diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index dff486cb00..84862bbcd4 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -3,21 +3,21 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_DETECT].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_KINGS_SHIELD].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_SILK_TRAP].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_SPIKY_SHIELD].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_WIDE_GUARD].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_QUICK_GUARD].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_CRAFTY_SHIELD].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_BANEFUL_BUNKER].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_BURNING_BULWARK].effect == EFFECT_PROTECT); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_LEER].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(!(gMovesInfo[MOVE_WATER_GUN].makesContact)); + ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_DETECT) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_KINGS_SHIELD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_SILK_TRAP) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_SPIKY_SHIELD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_WIDE_GUARD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_QUICK_GUARD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_CRAFTY_SHIELD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_BANEFUL_BUNKER) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_BURNING_BULWARK) == EFFECT_PROTECT); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveCategory(MOVE_LEER) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(!(MoveMakesContact(MOVE_WATER_GUN))); } SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield, Baneful Bunker and Burning Bulwark protect from all moves") @@ -244,10 +244,10 @@ SINGLE_BATTLE_TEST("Recoil damage is not applied if target was protected") GIVEN { - ASSUME(gMovesInfo[MOVE_VOLT_TACKLE].recoil > 0); - ASSUME(gMovesInfo[MOVE_HEAD_SMASH].recoil > 0); - ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil > 0); - ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil > 0); + ASSUME(GetMoveRecoil(MOVE_VOLT_TACKLE) > 0); + ASSUME(GetMoveRecoil(MOVE_HEAD_SMASH) > 0); + ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) > 0); + ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) > 0); PLAYER(SPECIES_RAPIDASH); OPPONENT(SPECIES_BEAUTIFLY); } WHEN { @@ -282,7 +282,7 @@ SINGLE_BATTLE_TEST("Multi-hit moves don't hit a protected target and fail only o PARAMETRIZE { move = MOVE_SPIKY_SHIELD; } GIVEN { - ASSUME(gMovesInfo[MOVE_ARM_THRUST].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_ARM_THRUST) == EFFECT_MULTI_HIT); PLAYER(SPECIES_RAPIDASH); OPPONENT(SPECIES_BEAUTIFLY); } WHEN { @@ -325,9 +325,9 @@ DOUBLE_BATTLE_TEST("Wide Guard protects self and ally from multi-target moves") PARAMETRIZE { move = MOVE_HYPER_VOICE; } // 2 foes GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].target == MOVE_TARGET_SELECTED); - ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_TACKLE) == MOVE_TARGET_SELECTED); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -364,7 +364,7 @@ DOUBLE_BATTLE_TEST("Wide Guard can not fail on consecutive turns") PASSES_RANDOMLY(2, 2); GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -397,8 +397,8 @@ DOUBLE_BATTLE_TEST("Quick Guard protects self and ally from priority moves") PARAMETRIZE { move = MOVE_QUICK_ATTACK; targetOpponent = opponentRight; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].priority == 0); - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_TACKLE) == 0); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -427,7 +427,7 @@ DOUBLE_BATTLE_TEST("Quick Guard can not fail on consecutive turns") PASSES_RANDOMLY(2, 2); GIVEN { - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -457,9 +457,9 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves") PARAMETRIZE { move = MOVE_TACKLE; targetOpponent = opponentRight; } GIVEN { - ASSUME(gMovesInfo[MOVE_LEER].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveTarget(MOVE_LEER) == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); + ASSUME(GetMoveCategory(MOVE_HYPER_VOICE) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -494,10 +494,10 @@ SINGLE_BATTLE_TEST("Protect does not block Confide or Decorate") PARAMETRIZE { move = MOVE_DECORATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_CONFIDE].ignoresProtect == TRUE); - ASSUME(gMovesInfo[MOVE_DECORATE].effect == EFFECT_DECORATE); - ASSUME(gMovesInfo[MOVE_DECORATE].ignoresProtect == TRUE); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(MoveIgnoresProtect(MOVE_CONFIDE)); + ASSUME(GetMoveEffect(MOVE_DECORATE) == EFFECT_DECORATE); + ASSUME(MoveIgnoresProtect(MOVE_DECORATE)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -516,10 +516,10 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide and Decora PARAMETRIZE { move = MOVE_DECORATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); - ASSUME(gMovesInfo[MOVE_CONFIDE].ignoresProtect == TRUE); - ASSUME(gMovesInfo[MOVE_DECORATE].effect == EFFECT_DECORATE); - ASSUME(gMovesInfo[MOVE_DECORATE].ignoresProtect == TRUE); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(MoveIgnoresProtect(MOVE_CONFIDE)); + ASSUME(GetMoveEffect(MOVE_DECORATE) == EFFECT_DECORATE); + ASSUME(MoveIgnoresProtect(MOVE_DECORATE)); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/terrain/psychic.c b/test/battle/move_effect/psychic_terrain.c similarity index 84% rename from test/battle/terrain/psychic.c rename to test/battle/move_effect/psychic_terrain.c index 9ac88f29da..b85653a0be 100644 --- a/test/battle/terrain/psychic.c +++ b/test/battle/move_effect/psychic_terrain.c @@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Psychic Terrain protects grounded battlers from priority mov } } -SINGLE_BATTLE_TEST("Psychic Terrain activates Psychic Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Psychic!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_PSYCHIC); - } -} - SINGLE_BATTLE_TEST("Psychic Terrain increases power of Psychic-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/pursuit.c b/test/battle/move_effect/pursuit.c index 5dfa3f8e33..ea64813e68 100644 --- a/test/battle/move_effect/pursuit.c +++ b/test/battle/move_effect/pursuit.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_PURSUIT].effect == EFFECT_PURSUIT); + ASSUME(GetMoveEffect(MOVE_PURSUIT) == EFFECT_PURSUIT); } SINGLE_BATTLE_TEST("Pursuit attacks a switching foe") @@ -29,9 +29,9 @@ SINGLE_BATTLE_TEST("Pursuit attacks a foe using Volt Switch / U-Turn / Parting S PARAMETRIZE { move = MOVE_U_TURN; } PARAMETRIZE { move = MOVE_PARTING_SHOT; } GIVEN { - ASSUME(gMovesInfo[MOVE_VOLT_SWITCH].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); - ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); + ASSUME(GetMoveEffect(MOVE_VOLT_SWITCH) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE); + ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_WYNAUT); @@ -51,9 +51,9 @@ DOUBLE_BATTLE_TEST("Pursuit doesn't attack a foe using Teleport / Baton Pass to PARAMETRIZE { move = MOVE_TELEPORT; } PARAMETRIZE { move = MOVE_BATON_PASS; } GIVEN { - ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH); - ASSUME(gMovesInfo[MOVE_TELEPORT].effect == EFFECT_TELEPORT); - ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH); + ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT); + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_NIDOKING); PLAYER(SPECIES_ZIGZAGOON); @@ -115,8 +115,8 @@ SINGLE_BATTLE_TEST("Pursuit ignores accuracy checks when attacking a switching t { PASSES_RANDOMLY(100, 100, RNG_ACCURACY); GIVEN { - ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); } PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_WOBBUFFET); @@ -340,7 +340,7 @@ SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and takes Life Orb damage") DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe but isn't affected by Follow Me") { GIVEN { - ASSUME(gMovesInfo[MOVE_FOLLOW_ME].effect == EFFECT_FOLLOW_ME); + ASSUME(GetMoveEffect(MOVE_FOLLOW_ME) == EFFECT_FOLLOW_ME); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_CLEFABLE); PLAYER(SPECIES_ZIGZAGOON); @@ -422,7 +422,7 @@ SINGLE_BATTLE_TEST("Pursuit user terastalizes before attacking a switching foe a DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against immune target") { GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_DONPHAN); PLAYER(SPECIES_HELIOLISK); PLAYER(SPECIES_ZIGZAGOON); @@ -441,7 +441,7 @@ DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against immune target") DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against target with Volt Absorb") { GIVEN { - ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY); + ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY); PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); } PLAYER(SPECIES_HELIOLISK); PLAYER(SPECIES_ZIGZAGOON); @@ -610,4 +610,67 @@ SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and switchin is correctly st } } +SINGLE_BATTLE_TEST("Pursuit doesn't cause mon with Emergency Exit to switch twice") +{ + GIVEN { + PLAYER(SPECIES_GOLISOPOD) { HP(101); MaxHP(200); Ability(ABILITY_EMERGENCY_EXIT); } + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_VOLTORB); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(player, 2); } + } SCENE { + SWITCH_OUT_MESSAGE("Golisopod"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent); + ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT); + SEND_IN_MESSAGE("Voltorb"); + } THEN { + EXPECT_EQ(player->species, SPECIES_VOLTORB); + } +} + +SINGLE_BATTLE_TEST("Pursuit user gets forced out by Red Card and target still switches out") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + PLAYER(SPECIES_VOLTORB); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_VOLTORB); + } WHEN { + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); } + } SCENE { + SWITCH_OUT_MESSAGE("Wobbuffet"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("The opposing Voltorb was dragged out!"); + SEND_IN_MESSAGE("Voltorb"); + } THEN { + EXPECT_EQ(player->species, SPECIES_VOLTORB); + EXPECT_EQ(opponent->species, SPECIES_VOLTORB); + } +} + +SINGLE_BATTLE_TEST("Pursuit user faints to Life Orb and target still switches out") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_VOLTORB); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); HP(1); } + OPPONENT(SPECIES_VOLTORB); + } WHEN { + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(opponent, 1); } + } SCENE { + SWITCH_OUT_MESSAGE("Wobbuffet"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent); + HP_BAR(opponent); + MESSAGE("The opposing Wobbuffet fainted!"); + SEND_IN_MESSAGE("Voltorb"); + } THEN { + EXPECT_EQ(player->species, SPECIES_VOLTORB); + EXPECT_EQ(opponent->species, SPECIES_VOLTORB); + } +} + TO_DO_BATTLE_TEST("Baton Pass doesn't cause Pursuit to increase its power or priority"); diff --git a/test/battle/move_effect/quash.c b/test/battle/move_effect/quash.c index b342eafd74..1d2f89230c 100644 --- a/test/battle/move_effect/quash.c +++ b/test/battle/move_effect/quash.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH); + ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH); } DOUBLE_BATTLE_TEST("Quash-affected target will move last in the priority bracket") @@ -27,7 +27,7 @@ DOUBLE_BATTLE_TEST("Quash is not affected by dynamic speed") { GIVEN { ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8); - ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); + ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); } PLAYER(SPECIES_WOBBUFFET) { Speed(30); } OPPONENT(SPECIES_TORCHIC) { Speed(50); } @@ -113,8 +113,8 @@ DOUBLE_BATTLE_TEST("Quash-affected mon that acted early via After You is not aff { GIVEN { ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8); - ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); - ASSUME(gMovesInfo[MOVE_AFTER_YOU].effect == EFFECT_AFTER_YOU); + ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); + ASSUME(GetMoveEffect(MOVE_AFTER_YOU) == EFFECT_AFTER_YOU); PLAYER(SPECIES_VOLBEAT) { Speed(20); Ability(ABILITY_PRANKSTER); } PLAYER(SPECIES_WOBBUFFET) { Speed(30); } OPPONENT(SPECIES_TORCHIC) { Speed(10); } diff --git a/test/battle/move_effect/rage_fist.c b/test/battle/move_effect/rage_fist.c index 7bc349cef0..7a87f3e34d 100644 --- a/test/battle/move_effect/rage_fist.c +++ b/test/battle/move_effect/rage_fist.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RAGE_FIST].effect == EFFECT_RAGE_FIST); - ASSUME(gMovesInfo[MOVE_RAGE_FIST].power == 50); + ASSUME(GetMoveEffect(MOVE_RAGE_FIST) == EFFECT_RAGE_FIST); + ASSUME(GetMovePower(MOVE_RAGE_FIST) == 50); } SINGLE_BATTLE_TEST("Rage Fist base power is increased by 50 if the user takes damage") @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Rage Fist base power is increased by each multi hit") s16 timesGotHit[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT); + ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_REGIROCK); } WHEN { @@ -130,7 +130,7 @@ SINGLE_BATTLE_TEST("Rage Fist base power is not increased if a substitute was hi s16 timesGotHit[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_CRUNCH].category == DAMAGE_CATEGORY_PHYSICAL); // Substitute doesn't fade otherwise + ASSUME(GetMoveCategory(MOVE_CRUNCH) == DAMAGE_CATEGORY_PHYSICAL); // Substitute doesn't fade otherwise PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_REGIROCK); } WHEN { diff --git a/test/battle/move_effect/raging_bull.c b/test/battle/move_effect/raging_bull.c index 7e72ca8273..c75c977495 100644 --- a/test/battle/move_effect/raging_bull.c +++ b/test/battle/move_effect/raging_bull.c @@ -3,11 +3,11 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RAGING_BULL].effect == EFFECT_RAGING_BULL); - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); - ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN); - ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT); - ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL); + ASSUME(GetMoveEffect(MOVE_RAGING_BULL) == EFFECT_RAGING_BULL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN); + ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT); + ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL); } SINGLE_BATTLE_TEST("Raging Bull removes Light Screen, Reflect and Aurora Veil from the target's side of the field") diff --git a/test/battle/move_effect/recoil_if_miss.c b/test/battle/move_effect/recoil_if_miss.c index a5f0111095..8695156dd0 100644 --- a/test/battle/move_effect/recoil_if_miss.c +++ b/test/battle/move_effect/recoil_if_miss.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_JUMP_KICK].effect == EFFECT_RECOIL_IF_MISS); + ASSUME(GetMoveEffect(MOVE_JUMP_KICK) == EFFECT_RECOIL_IF_MISS); } SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss") @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss") SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect") { GIVEN { - ASSUME(!gMovesInfo[MOVE_JUMP_KICK].ignoresProtect); + ASSUME(!MoveIgnoresProtect(MOVE_JUMP_KICK)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pok PARAMETRIZE { hp = maxHp / 8; faintOnSpiky = TRUE; } // Faints after Spiky Shield's recoil GIVEN { - ASSUME(gMovesInfo[MOVE_SPIKY_SHIELD].effect == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_SPIKY_SHIELD) == EFFECT_PROTECT); PLAYER(SPECIES_WOBBUFFET) { HP(hp); MaxHP(maxHp); } PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/reflect.c b/test/battle/move_effect/reflect.c index 429dc6f696..83ac3b8503 100644 --- a/test/battle/move_effect/reflect.c +++ b/test/battle/move_effect/reflect.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT); + ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT); } SINGLE_BATTLE_TEST("Reflect reduces physical damage", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Reflect reduces physical damage", s16 damage) PARAMETRIZE { move = MOVE_CELEBRATE; } PARAMETRIZE { move = MOVE_REFLECT; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Reflect applies for 5 turns") { s16 damage[6]; GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/refresh.c b/test/battle/move_effect/refresh.c index 7cf319f3e6..7d0ba0273e 100644 --- a/test/battle/move_effect/refresh.c +++ b/test/battle/move_effect/refresh.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_REFRESH].effect == EFFECT_REFRESH); + ASSUME(GetMoveEffect(MOVE_REFRESH) == EFFECT_REFRESH); } SINGLE_BATTLE_TEST("Refresh cures the user of burn, frostbite, poison, and paralysis") @@ -45,8 +45,8 @@ SINGLE_BATTLE_TEST("Refresh does not cure the user of Freeze") SINGLE_BATTLE_TEST("Refresh does not cure sleep when used by Sleep Talk") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_REFRESH); } } WHEN { diff --git a/test/battle/move_effect/relic_song.c b/test/battle/move_effect/relic_song.c index e7569c7e38..f1e7fae92f 100644 --- a/test/battle/move_effect/relic_song.c +++ b/test/battle/move_effect/relic_song.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RELIC_SONG].effect == EFFECT_RELIC_SONG); + ASSUME(GetMoveEffect(MOVE_RELIC_SONG) == EFFECT_RELIC_SONG); ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE); } diff --git a/test/battle/move_effect/retaliate.c b/test/battle/move_effect/retaliate.c index 581793e854..39c26d196c 100644 --- a/test/battle/move_effect/retaliate.c +++ b/test/battle/move_effect/retaliate.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RETALIATE].effect == EFFECT_RETALIATE); + ASSUME(GetMoveEffect(MOVE_RETALIATE) == EFFECT_RETALIATE); } SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faints") @@ -63,17 +63,17 @@ DOUBLE_BATTLE_TEST("Retaliate works with passive damage") PARAMETRIZE { move = MOVE_FLAME_BURST; moveTarget = playerRight; } PARAMETRIZE { move = MOVE_FIRE_PLEDGE; moveTarget = playerRight; move2 = MOVE_GRASS_PLEDGE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); - ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); - ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON); + ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP); #if B_USE_FROSTBITE == TRUE - ASSUME(gMovesInfo[MOVE_ICE_BEAM].additionalEffects[0].moveEffect == MOVE_EFFECT_FREEZE_OR_FROSTBITE); + ASSUME(GetMoveAdditionalEffectById(MOVE_ICE_BEAM, 0)->moveEffect == MOVE_EFFECT_FREEZE_OR_FROSTBITE); #endif - ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM); - ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); - ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED); - ASSUME(gMovesInfo[MOVE_MAGMA_STORM].additionalEffects[0].moveEffect == MOVE_EFFECT_WRAP); - ASSUME(gMovesInfo[MOVE_FLAME_BURST].additionalEffects[0].moveEffect == MOVE_EFFECT_FLAME_BURST); + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED); + ASSUME(GetMoveAdditionalEffectById(MOVE_MAGMA_STORM, 0)->moveEffect == MOVE_EFFECT_WRAP); + ASSUME(GetMoveAdditionalEffectById(MOVE_FLAME_BURST, 0)->moveEffect == MOVE_EFFECT_FLAME_BURST); PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); HP(18); } PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); } PLAYER(SPECIES_WOBBUFFET); @@ -97,7 +97,7 @@ SINGLE_BATTLE_TEST("Retaliate works with Perish Song") { s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_PERISH_SONG].effect == EFFECT_PERISH_SONG); + ASSUME(GetMoveEffect(MOVE_PERISH_SONG) == EFFECT_PERISH_SONG); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_KOMMO_O) { Ability(ABILITY_SOUNDPROOF); } @@ -120,7 +120,7 @@ SINGLE_BATTLE_TEST("Retaliate works with self-inflicted fainting") { s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH); + ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/revelation_dance.c b/test/battle/move_effect/revelation_dance.c index 9ab5d4a8e2..3730ecc0b2 100644 --- a/test/battle/move_effect/revelation_dance.c +++ b/test/battle/move_effect/revelation_dance.c @@ -3,12 +3,12 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE); - ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE); - ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE)); - ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE); - ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS); - ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST); + ASSUME(GetMoveEffect(MOVE_REVELATION_DANCE) == EFFECT_REVELATION_DANCE); + ASSUME(IsDanceMove(MOVE_REVELATION_DANCE)); + ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE)); + ASSUME(GetMoveEffect(MOVE_FORESTS_CURSE) == EFFECT_THIRD_TYPE); + ASSUME(GetMoveArgType(MOVE_FORESTS_CURSE) == TYPE_GRASS); + ASSUME(GetMoveEffect(MOVE_ROOST) == EFFECT_ROOST); } SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 1st Type") diff --git a/test/battle/move_effect/revival_blessing.c b/test/battle/move_effect/revival_blessing.c index dbeda39f91..10198ce352 100644 --- a/test/battle/move_effect/revival_blessing.c +++ b/test/battle/move_effect/revival_blessing.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_REVIVAL_BLESSING].effect == EFFECT_REVIVAL_BLESSING); + ASSUME(GetMoveEffect(MOVE_REVIVAL_BLESSING) == EFFECT_REVIVAL_BLESSING); } SINGLE_BATTLE_TEST("Revival Blessing revives a chosen fainted party member for the player") diff --git a/test/battle/move_effect/roar.c b/test/battle/move_effect/roar.c index f67a24bba1..ef6439088f 100644 --- a/test/battle/move_effect/roar.c +++ b/test/battle/move_effect/roar.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR); + ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR); } SINGLE_BATTLE_TEST("Roar switches the target with a random non-fainted replacement") diff --git a/test/battle/move_effect/role_play.c b/test/battle/move_effect/role_play.c index ab0d801ee9..d2d937f7d1 100644 --- a/test/battle/move_effect/role_play.c +++ b/test/battle/move_effect/role_play.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY); + ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY); } SINGLE_BATTLE_TEST("Role Play copies target's ability") diff --git a/test/battle/move_effect/roost.c b/test/battle/move_effect/roost.c index 449119a89a..51d9499bd1 100644 --- a/test/battle/move_effect/roost.c +++ b/test/battle/move_effect/roost.c @@ -3,28 +3,28 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST); + ASSUME(GetMoveEffect(MOVE_ROOST) == EFFECT_ROOST); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FLYING); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FLYING); // One attack of each type to verify typelessness - ASSUME(gMovesInfo[MOVE_POUND].type == TYPE_NORMAL); - ASSUME(gMovesInfo[MOVE_KARATE_CHOP].type == TYPE_FIGHTING); - ASSUME(gMovesInfo[MOVE_GUST].type == TYPE_FLYING); - ASSUME(gMovesInfo[MOVE_POISON_STING].type == TYPE_POISON); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND); - ASSUME(gMovesInfo[MOVE_ROCK_THROW].type == TYPE_ROCK); - ASSUME(gMovesInfo[MOVE_LEECH_LIFE].type == TYPE_BUG); - ASSUME(gMovesInfo[MOVE_LICK].type == TYPE_GHOST); - ASSUME(gMovesInfo[MOVE_STEEL_WING].type == TYPE_STEEL); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS); - ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); - ASSUME(gMovesInfo[MOVE_CONFUSION].type == TYPE_PSYCHIC); - ASSUME(gMovesInfo[MOVE_ICE_BEAM].type == TYPE_ICE); - ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].type == TYPE_DRAGON); - ASSUME(gMovesInfo[MOVE_BITE].type == TYPE_DARK); - ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].type == TYPE_FAIRY); + ASSUME(GetMoveType(MOVE_POUND) == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_KARATE_CHOP) == TYPE_FIGHTING); + ASSUME(GetMoveType(MOVE_GUST) == TYPE_FLYING); + ASSUME(GetMoveType(MOVE_POISON_STING) == TYPE_POISON); + ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_ROCK_THROW) == TYPE_ROCK); + ASSUME(GetMoveType(MOVE_LEECH_LIFE) == TYPE_BUG); + ASSUME(GetMoveType(MOVE_LICK) == TYPE_GHOST); + ASSUME(GetMoveType(MOVE_STEEL_WING) == TYPE_STEEL); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); + ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_CONFUSION) == TYPE_PSYCHIC); + ASSUME(GetMoveType(MOVE_ICE_BEAM) == TYPE_ICE); + ASSUME(GetMoveType(MOVE_DRAGON_BREATH) == TYPE_DRAGON); + ASSUME(GetMoveType(MOVE_BITE) == TYPE_DARK); + ASSUME(GetMoveType(MOVE_DISARMING_VOICE) == TYPE_FAIRY); } SINGLE_BATTLE_TEST("Roost fails when user is at full HP") diff --git a/test/battle/move_effect/round.c b/test/battle/move_effect/round.c index 09209c79a2..0bac324b0f 100644 --- a/test/battle/move_effect/round.c +++ b/test/battle/move_effect/round.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ROUND].effect == EFFECT_ROUND); + ASSUME(GetMoveEffect(MOVE_ROUND) == EFFECT_ROUND); } DOUBLE_BATTLE_TEST("Round allows other battlers which also selected the moves to immediately use the move, ignoring turn order") { GIVEN { ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL); - ASSUME(gMovesInfo[MOVE_IRON_HEAD].additionalEffects[0].moveEffect == MOVE_EFFECT_FLINCH); + ASSUME(GetMoveAdditionalEffectById(MOVE_IRON_HEAD, 0)->moveEffect == MOVE_EFFECT_FLINCH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/salt_cure.c b/test/battle/move_effect/salt_cure.c index 495a7e8c80..94e3ead5cc 100644 --- a/test/battle/move_effect/salt_cure.c +++ b/test/battle/move_effect/salt_cure.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SALT_CURE].effect == EFFECT_SALT_CURE); + ASSUME(MoveHasAdditionalEffect(MOVE_SALT_CURE, MOVE_EFFECT_SALT_CURE) == TRUE); } SINGLE_BATTLE_TEST("Salt Cure inflicts 1/8 of the target's maximum HP as damage per turn") @@ -117,3 +117,18 @@ SINGLE_BATTLE_TEST("Salt Cure residual damage does not inflict any damage agains } } } + +SINGLE_BATTLE_TEST("If Salt Cure faints the target, messages will be applied in the correct order") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(25); } + } WHEN { + TURN { MOVE(player, MOVE_SALT_CURE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SALT_CURE, player); + MESSAGE("The opposing Wobbuffet is being salt cured!"); + MESSAGE("The opposing Wobbuffet is hurt by Salt Cure!"); + MESSAGE("The opposing Wobbuffet fainted!"); + } +} diff --git a/test/battle/move_effect/semi_invulnerable.c b/test/battle/move_effect/semi_invulnerable.c index d3869bfe54..331413121c 100644 --- a/test/battle/move_effect/semi_invulnerable.c +++ b/test/battle/move_effect/semi_invulnerable.c @@ -3,18 +3,18 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_FLY].argument)) == STATUS3_ON_AIR); - ASSUME(gMovesInfo[MOVE_DIG].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_DIG].argument)) == STATUS3_UNDERGROUND); - ASSUME(gMovesInfo[MOVE_BOUNCE].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_BOUNCE].argument)) == STATUS3_ON_AIR); - ASSUME(gMovesInfo[MOVE_DIVE].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_DIVE].argument)) == STATUS3_UNDERWATER); - ASSUME(gMovesInfo[MOVE_PHANTOM_FORCE].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_PHANTOM_FORCE].argument)) == STATUS3_PHANTOM_FORCE); - ASSUME(gMovesInfo[MOVE_SHADOW_FORCE].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_SHADOW_FORCE].argument)) == STATUS3_PHANTOM_FORCE); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR); + ASSUME(GetMoveEffect(MOVE_DIG) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIG) == STATUS3_UNDERGROUND); + ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR); + ASSUME(GetMoveEffect(MOVE_DIVE) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIVE) == STATUS3_UNDERWATER); + ASSUME(GetMoveEffect(MOVE_PHANTOM_FORCE) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_PHANTOM_FORCE) == STATUS3_PHANTOM_FORCE); + ASSUME(GetMoveEffect(MOVE_SHADOW_FORCE) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SHADOW_FORCE) == STATUS3_PHANTOM_FORCE); } SINGLE_BATTLE_TEST("Semi-invulnerable moves make the user semi-invulnerable turn 1, then strike turn 2") diff --git a/test/battle/move_effect/shed_tail.c b/test/battle/move_effect/shed_tail.c index f4ef2ec0d5..4667eab1ad 100644 --- a/test/battle/move_effect/shed_tail.c +++ b/test/battle/move_effect/shed_tail.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SHED_TAIL].effect == EFFECT_SHED_TAIL); + ASSUME(GetMoveEffect(MOVE_SHED_TAIL) == EFFECT_SHED_TAIL); } SINGLE_BATTLE_TEST("Shed Tail creates a Substitute at the cost of 1/2 users maximum HP and switches the user out") @@ -110,8 +110,8 @@ SINGLE_BATTLE_TEST("Shed Tail creates a Substitute with 1/4 of user maximum heal PARAMETRIZE { hp = 164; } GIVEN { - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40); - ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40); + ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG); PLAYER(SPECIES_BULBASAUR) { MaxHP(hp); } PLAYER(SPECIES_BULBASAUR); OPPONENT(SPECIES_CHARMANDER); diff --git a/test/battle/move_effect/shell_trap.c b/test/battle/move_effect/shell_trap.c index d43893244a..f121d1444d 100644 --- a/test/battle/move_effect/shell_trap.c +++ b/test/battle/move_effect/shell_trap.c @@ -3,10 +3,10 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].effect == EFFECT_SHELL_TRAP); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_LEER].category == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMoveEffect(MOVE_SHELL_TRAP) == EFFECT_SHELL_TRAP); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_LEER) == DAMAGE_CATEGORY_STATUS); } SINGLE_BATTLE_TEST("Shell Trap activates only if hit by a physical move") @@ -98,7 +98,7 @@ SINGLE_BATTLE_TEST("Shell Trap does not activate if battler faints before being DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 1 and attacks both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } PLAYER(SPECIES_WOBBUFFET) { Speed(2); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); } @@ -122,7 +122,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 1 a DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 2 and attacks both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } PLAYER(SPECIES_WOBBUFFET) { Speed(2); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); } @@ -146,7 +146,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 2 a DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 3 and attacks both opponents") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } PLAYER(SPECIES_WOBBUFFET) { Speed(7); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); } @@ -170,7 +170,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 3 a DOUBLE_BATTLE_TEST("Shell Trap targets correctly if one of the opponents has fainted") { GIVEN { - ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH); PLAYER(SPECIES_GRENINJA) { Speed(60); } PLAYER(SPECIES_TURTONATOR) { Speed(10); } OPPONENT(SPECIES_BLASTOISE) { Speed(120); } diff --git a/test/battle/move_effect/simple_beam.c b/test/battle/move_effect/simple_beam.c index e91bf0b8ce..4250c8ce45 100644 --- a/test/battle/move_effect/simple_beam.c +++ b/test/battle/move_effect/simple_beam.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM); + ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM); } SINGLE_BATTLE_TEST("Simple Beam replaces target's ability with Simple") diff --git a/test/battle/move_effect/skill_swap.c b/test/battle/move_effect/skill_swap.c index 9c31ae59a7..c3c2ca91f4 100644 --- a/test/battle/move_effect/skill_swap.c +++ b/test/battle/move_effect/skill_swap.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP); + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); } SINGLE_BATTLE_TEST("Skill Swap swaps user and target's abilities") diff --git a/test/battle/move_effect/sleep.c b/test/battle/move_effect/sleep.c index 834f606672..702044d331 100644 --- a/test/battle/move_effect/sleep.c +++ b/test/battle/move_effect/sleep.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP); } SINGLE_BATTLE_TEST("Hypnosis inflicts 1-3 turns of sleep") diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c index 8ecd600f36..4ac89e69d8 100644 --- a/test/battle/move_effect/sleep_talk.c +++ b/test/battle/move_effect/sleep_talk.c @@ -3,10 +3,10 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); - ASSUME(gMovesInfo[MOVE_RAZOR_WIND].sleepTalkBanned == TRUE); - ASSUME(gMovesInfo[MOVE_FLY].sleepTalkBanned == TRUE); - ASSUME(gMovesInfo[MOVE_DIG].sleepTalkBanned == TRUE); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); + ASSUME(IsMoveSleepTalkBanned(MOVE_RAZOR_WIND)); + ASSUME(IsMoveSleepTalkBanned(MOVE_FLY)); + ASSUME(IsMoveSleepTalkBanned(MOVE_DIG)); } SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep") diff --git a/test/battle/move_effect/smelling_salts.c b/test/battle/move_effect/smelling_salts.c index bb3f333a42..6b1d0b2d7e 100644 --- a/test/battle/move_effect/smelling_salts.c +++ b/test/battle/move_effect/smelling_salts.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_SMELLING_SALTS, MOVE_EFFECT_REMOVE_STATUS) == TRUE); - ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].argument == STATUS1_PARALYSIS); + ASSUME(GetMoveEffectArg_Status(MOVE_SMELLING_SALTS) == STATUS1_PARALYSIS); } SINGLE_BATTLE_TEST("Smelling Salts does not cure paralyzed pokemons behind substitutes or get increased power") diff --git a/test/battle/move_effect/solar_beam.c b/test/battle/move_effect/solar_beam.c new file mode 100644 index 0000000000..309d950c50 --- /dev/null +++ b/test/battle/move_effect/solar_beam.c @@ -0,0 +1,34 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_SOLAR_BEAM) == EFFECT_SOLAR_BEAM); + ASSUME(GetMoveTwoTurnAttackWeather(MOVE_SOLAR_BLADE) == B_WEATHER_SUN); +} + +SINGLE_BATTLE_TEST("Solar Beam does not need a charging turn if Sun is up") +{ + u32 ability; + + PARAMETRIZE { ability = ABILITY_DROUGHT; } + PARAMETRIZE { ability = ABILITY_WHITE_SMOKE; } + + GIVEN { + PLAYER(SPECIES_TORKOAL) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SOLAR_BEAM); } + if (ability == ABILITY_WHITE_SMOKE) { + TURN { SKIP_TURN(player); } + } + } SCENE { + if (ability == ABILITY_WHITE_SMOKE) { + MESSAGE("Torkoal used Solar Beam!"); + MESSAGE("Torkoal absorbed light!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + } + MESSAGE("Torkoal used Solar Beam!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SOLAR_BEAM, player); + } +} diff --git a/test/battle/move_effect/sparkling_aria.c b/test/battle/move_effect/sparkling_aria.c index 332cf8165c..86b906228b 100644 --- a/test/battle/move_effect/sparkling_aria.c +++ b/test/battle/move_effect/sparkling_aria.c @@ -4,8 +4,8 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLING_ARIA, MOVE_EFFECT_REMOVE_STATUS) == TRUE); - ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].argument == STATUS1_BURN); - ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].soundMove == TRUE); + ASSUME(GetMoveEffectArg_Status(MOVE_SPARKLING_ARIA) == STATUS1_BURN); + ASSUME(IsSoundMove(MOVE_SPARKLING_ARIA)); } DOUBLE_BATTLE_TEST("Sparkling Aria cures burns from all Pokemon on the field and behind substitutes") diff --git a/test/battle/move_effect/special_attack_down.c b/test/battle/move_effect/special_attack_down.c index 60d015d1cd..63ca071fc1 100644 --- a/test/battle/move_effect/special_attack_down.c +++ b/test/battle/move_effect/special_attack_down.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN); } SINGLE_BATTLE_TEST("Confide lowers Special Attack", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Confide lowers Special Attack", s16 damage) PARAMETRIZE { lowerSpecialAttack = FALSE; } PARAMETRIZE { lowerSpecialAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/special_attack_up_3.c b/test/battle/move_effect/special_attack_up_3.c index a701893f51..75f6c4b36d 100644 --- a/test/battle/move_effect/special_attack_up_3.c +++ b/test/battle/move_effect/special_attack_up_3.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAIL_GLOW].effect == EFFECT_SPECIAL_ATTACK_UP_3); + ASSUME(GetMoveEffect(MOVE_TAIL_GLOW) == EFFECT_SPECIAL_ATTACK_UP_3); } SINGLE_BATTLE_TEST("Tail Glow drastically raises Special Attack", s16 damage) @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Tail Glow drastically raises Special Attack", s16 damage) PARAMETRIZE { raiseSpecialAttack = FALSE; } PARAMETRIZE { raiseSpecialAttack = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/spicy_extract.c b/test/battle/move_effect/spicy_extract.c index c9ddb3c30d..b5fe1da0f1 100644 --- a/test/battle/move_effect/spicy_extract.c +++ b/test/battle/move_effect/spicy_extract.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SPICY_EXTRACT].effect == EFFECT_SPICY_EXTRACT); + ASSUME(GetMoveEffect(MOVE_SPICY_EXTRACT) == EFFECT_SPICY_EXTRACT); } SINGLE_BATTLE_TEST("Spicy Extract raises target's Attack by 2 stages and lowers target's Defense by 2 stages") @@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Spicy Extract is prevented by target's ability if it's Attac PARAMETRIZE { ability = ABILITY_LIGHT_METAL; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BELDUM) { Ability(ability); } } WHEN { diff --git a/test/battle/move_effect/spikes.c b/test/battle/move_effect/spikes.c index 339a9f9a4b..187b9ce7ac 100644 --- a/test/battle/move_effect/spikes.c +++ b/test/battle/move_effect/spikes.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES); + ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES); } SINGLE_BATTLE_TEST("Spikes damage on switch in") diff --git a/test/battle/move_effect/stealth_rock.c b/test/battle/move_effect/stealth_rock.c index 9a38f17a5e..d4399a2d0f 100644 --- a/test/battle/move_effect/stealth_rock.c +++ b/test/battle/move_effect/stealth_rock.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK); + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); } SINGLE_BATTLE_TEST("Stealth Rock damage on switch in based on typing") diff --git a/test/battle/move_effect/sticky_web.c b/test/battle/move_effect/sticky_web.c index e99368aa7d..ed0f6e5d93 100644 --- a/test/battle/move_effect/sticky_web.c +++ b/test/battle/move_effect/sticky_web.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB); + ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB); } SINGLE_BATTLE_TEST("Sticky Web lowers Speed by 1 on switch-in") @@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Sticky Web can only be set up 1 time") DOUBLE_BATTLE_TEST("Sticky Web lowers Speed by 1 in a double battle after Explosion fainting both mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION); + ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION); PLAYER(SPECIES_WOBBUFFET) {Speed(5);} PLAYER(SPECIES_WOBBUFFET) {HP(1500); Speed(10);} PLAYER(SPECIES_WOBBUFFET) {Speed(10);} @@ -197,7 +197,7 @@ DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - no o PARAMETRIZE {hasReplacement = FALSE;} GIVEN { - ASSUME(gMovesInfo[MOVE_MEMENTO].effect == EFFECT_MEMENTO); + ASSUME(GetMoveEffect(MOVE_MEMENTO) == EFFECT_MEMENTO); PLAYER(SPECIES_SQUIRTLE) {Speed(5); } PLAYER(SPECIES_CHARMANDER) {Speed(5); } PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); Speed(5); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web. diff --git a/test/battle/move_effect/stockpile.c b/test/battle/move_effect/stockpile.c index f6c3f02a46..f045fa6823 100644 --- a/test/battle/move_effect/stockpile.c +++ b/test/battle/move_effect/stockpile.c @@ -4,9 +4,9 @@ // These tests cover all 3 effects: Stockpile, Spit up and Swallow. ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STOCKPILE].effect == EFFECT_STOCKPILE); - ASSUME(gMovesInfo[MOVE_SWALLOW].effect == EFFECT_SWALLOW); - ASSUME(gMovesInfo[MOVE_SPIT_UP].effect == EFFECT_SPIT_UP); + ASSUME(GetMoveEffect(MOVE_STOCKPILE) == EFFECT_STOCKPILE); + ASSUME(GetMoveEffect(MOVE_SWALLOW) == EFFECT_SWALLOW); + ASSUME(GetMoveEffect(MOVE_SPIT_UP) == EFFECT_SPIT_UP); } SINGLE_BATTLE_TEST("Stockpile's count can go up only to 3") @@ -148,8 +148,8 @@ SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp. Def", s16 dmgPyhsic PARAMETRIZE { move = MOVE_CELEBRATE; } GIVEN { ASSUME(B_STOCKPILE_RAISES_DEFS >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET) { Speed(2); } OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } } WHEN { @@ -184,8 +184,8 @@ DOUBLE_BATTLE_TEST("Stockpile's Def and Sp. Def boost is lost after using Spit U PARAMETRIZE { count = 3; move = MOVE_SPIT_UP; } GIVEN { ASSUME(B_STOCKPILE_RAISES_DEFS >= GEN_4); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET) { Speed(4); HP(399); MaxHP(400); } PLAYER(SPECIES_WOBBUFFET) { Speed(3); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } diff --git a/test/battle/move_effect/stomping_tantrum.c b/test/battle/move_effect/stomping_tantrum.c index 32747282e4..c759de38b1 100644 --- a/test/battle/move_effect/stomping_tantrum.c +++ b/test/battle/move_effect/stomping_tantrum.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STOMPING_TANTRUM].effect == EFFECT_STOMPING_TANTRUM); + ASSUME(GetMoveEffect(MOVE_STOMPING_TANTRUM) == EFFECT_STOMPING_TANTRUM); } SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user flinched on the previous turn") diff --git a/test/battle/move_effect/strength_sap.c b/test/battle/move_effect/strength_sap.c index 0246d0881f..c38048ba8f 100644 --- a/test/battle/move_effect/strength_sap.c +++ b/test/battle/move_effect/strength_sap.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STRENGTH_SAP].effect == EFFECT_STRENGTH_SAP); + ASSUME(GetMoveEffect(MOVE_STRENGTH_SAP) == EFFECT_STRENGTH_SAP); } SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on target's Attack Stat", s16 hp) @@ -69,8 +69,8 @@ SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on tar } GIVEN { - ASSUME(gMovesInfo[MOVE_WORK_UP].effect == EFFECT_ATTACK_SPATK_UP); - ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(GetMoveEffect(MOVE_WORK_UP) == EFFECT_ATTACK_SPATK_UP); + ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN); PLAYER(SPECIES_WOBBUFFET) { HP(50); } OPPONENT(SPECIES_WOBBUFFET) { Attack(60); } } WHEN { @@ -117,7 +117,7 @@ SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on tar SINGLE_BATTLE_TEST("Strength Sap fails if target is at -6 Atk") { GIVEN { - ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); + ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -165,34 +165,3 @@ SINGLE_BATTLE_TEST("Strength Sap restores more HP if Big Root is held", s16 hp) EXPECT_GT(abs(results[1].hp), abs(results[0].hp)); } } - -SINGLE_BATTLE_TEST("Strength Sap makes attacker lose HP if target's ability is Liquid Ooze") -{ - s16 lostHp; - s32 atkStat; - - PARAMETRIZE { atkStat = 100; } - PARAMETRIZE { atkStat = 490; } // Checks that attacker can faint with no problems. - - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { Attack(atkStat); Ability(ABILITY_LIQUID_OOZE); } - } WHEN { - TURN { MOVE(player, MOVE_STRENGTH_SAP); if (atkStat == 490) { SEND_OUT(player, 1); } } - } SCENE { - MESSAGE("Wobbuffet used Strength Sap!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); - MESSAGE("The opposing Wobbuffet's Attack fell!"); - ABILITY_POPUP(opponent, ABILITY_LIQUID_OOZE); - HP_BAR(player, captureDamage: &lostHp); - MESSAGE("Wobbuffet sucked up the liquid ooze!"); - if (atkStat >= 490) { - MESSAGE("Wobbuffet fainted!"); - SEND_IN_MESSAGE("Wobbuffet"); - } - } THEN { - EXPECT_EQ(lostHp, atkStat); - } -} diff --git a/test/battle/move_effect/stuff_cheeks.c b/test/battle/move_effect/stuff_cheeks.c index 3bb3f22925..9e6a34c306 100644 --- a/test/battle/move_effect/stuff_cheeks.c +++ b/test/battle/move_effect/stuff_cheeks.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS); + ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS); ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].pocket == POCKET_BERRIES); ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP); } @@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("Stuff Cheeks can be used even if Magic Room is active") SINGLE_BATTLE_TEST("Stuff Cheeks fails if the user's berry is removed before they use the move") { GIVEN { - ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF); + ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF); PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/substitute.c b/test/battle/move_effect/substitute.c index 92e894fa07..e94767b660 100644 --- a/test/battle/move_effect/substitute.c +++ b/test/battle/move_effect/substitute.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE); + ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE); } SINGLE_BATTLE_TEST("Substitute creates a Substitute at the cost of 1/4 users maximum HP") diff --git a/test/battle/move_effect/super_effective_on_arg.c b/test/battle/move_effect/super_effective_on_arg.c index d10b8a2231..2569ccb109 100644 --- a/test/battle/move_effect/super_effective_on_arg.c +++ b/test/battle/move_effect/super_effective_on_arg.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_FREEZE_DRY].effect == EFFECT_SUPER_EFFECTIVE_ON_ARG); + ASSUME(GetMoveEffect(MOVE_FREEZE_DRY) == EFFECT_SUPER_EFFECTIVE_ON_ARG); } SINGLE_BATTLE_TEST("Freeze Dry is super effective on water types") diff --git a/test/battle/move_effect/synthesis.c b/test/battle/move_effect/synthesis.c index e4a2b77869..6799bd2870 100644 --- a/test/battle/move_effect/synthesis.c +++ b/test/battle/move_effect/synthesis.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SYNTHESIS].effect == EFFECT_SYNTHESIS); + ASSUME(GetMoveEffect(MOVE_SYNTHESIS) == EFFECT_SYNTHESIS); } SINGLE_BATTLE_TEST("Synthesis recovers 1/2 of the user's max HP") diff --git a/test/battle/move_effect/tailwind.c b/test/battle/move_effect/tailwind.c index 5fa5356451..f105c9612a 100644 --- a/test/battle/move_effect/tailwind.c +++ b/test/battle/move_effect/tailwind.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); + ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); } SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") diff --git a/test/battle/move_effect/take_heart.c b/test/battle/move_effect/take_heart.c index 2961725b22..e029439103 100644 --- a/test/battle/move_effect/take_heart.c +++ b/test/battle/move_effect/take_heart.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART); + ASSUME(GetMoveEffect(MOVE_TAKE_HEART) == EFFECT_TAKE_HEART); } SINGLE_BATTLE_TEST("Take Heart increases Sp. Atk and Sp. Def by one stage") @@ -50,8 +50,8 @@ SINGLE_BATTLE_TEST("Take Heart cures the user of all status conditions") SINGLE_BATTLE_TEST("Take Heart cures sleep when used by Sleep Talk") { GIVEN { - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_TAKE_HEART); } } WHEN { diff --git a/test/battle/move_effect/tar_shot.c b/test/battle/move_effect/tar_shot.c index 2b780577ec..f2aac4e552 100644 --- a/test/battle/move_effect/tar_shot.c +++ b/test/battle/move_effect/tar_shot.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TAR_SHOT].effect == EFFECT_TAR_SHOT); + ASSUME(GetMoveEffect(MOVE_TAR_SHOT) == EFFECT_TAR_SHOT); } SINGLE_BATTLE_TEST("Tar Shot doubles the effectiveness of Fire-type moves used on the target") @@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Tar Shot doubles the effectiveness of Fire-type moves used o ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC); ASSUME(gSpeciesInfo[SPECIES_OMASTAR].types[0] == TYPE_ROCK); ASSUME(gSpeciesInfo[SPECIES_OMASTAR].types[1] == TYPE_WATER); - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); GIVEN { PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/teatime.c b/test/battle/move_effect/teatime.c index dfdc70c801..fc4ad22198 100644 --- a/test/battle/move_effect/teatime.c +++ b/test/battle/move_effect/teatime.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TEATIME].effect == EFFECT_TEATIME); + ASSUME(GetMoveEffect(MOVE_TEATIME) == EFFECT_TEATIME); ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP); } diff --git a/test/battle/move_effect/telekinesis.c b/test/battle/move_effect/telekinesis.c index 746c42d053..31390d9733 100644 --- a/test/battle/move_effect/telekinesis.c +++ b/test/battle/move_effect/telekinesis.c @@ -3,14 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TELEKINESIS].effect == EFFECT_TELEKINESIS); + ASSUME(GetMoveEffect(MOVE_TELEKINESIS) == EFFECT_TELEKINESIS); } SINGLE_BATTLE_TEST("Telekinesis makes the target unable to avoid any attacks made against it") { GIVEN { - ASSUME(gMovesInfo[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE); // Raises evs by 2 - ASSUME(gMovesInfo[MOVE_SCREECH].accuracy < 100); + ASSUME(GetMoveEffect(MOVE_MINIMIZE) == EFFECT_MINIMIZE); // Raises evs by 2 + ASSUME(GetMoveAccuracy(MOVE_SCREECH) < 100); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); } WHEN { @@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Telekinesis ends after 3 turns") SINGLE_BATTLE_TEST("Telekinesis makes the target immune to Ground-type attacks") { GIVEN { - ASSUME(gMovesInfo[MOVE_BULLDOZE].type == TYPE_GROUND); + ASSUME(GetMoveType(MOVE_BULLDOZE) == TYPE_GROUND); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); } WHEN { diff --git a/test/battle/move_effect/teleport.c b/test/battle/move_effect/teleport.c index 3c79cb54ff..f77dffc658 100644 --- a/test/battle/move_effect/teleport.c +++ b/test/battle/move_effect/teleport.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TELEPORT].effect == EFFECT_TELEPORT); + ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT); } SINGLE_BATTLE_TEST("Teleport fails when there is no pokemon to switch in") diff --git a/test/battle/move_effect/tera_blast.c b/test/battle/move_effect/tera_blast.c index 80e960a1af..63e7a776b9 100644 --- a/test/battle/move_effect/tera_blast.c +++ b/test/battle/move_effect/tera_blast.c @@ -3,13 +3,13 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST); + ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST); } SINGLE_BATTLE_TEST("Tera Blast changes from Normal-type to the user's Tera Type") { GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_BLAST].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TERA_BLAST) == TYPE_NORMAL); PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_DARK); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effect/tera_starstorm.c b/test/battle/move_effect/tera_starstorm.c index b6b4571644..3077b38df9 100644 --- a/test/battle/move_effect/tera_starstorm.c +++ b/test/battle/move_effect/tera_starstorm.c @@ -3,13 +3,13 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].effect == EFFECT_TERA_STARSTORM); + ASSUME(GetMoveEffect(MOVE_TERA_STARSTORM) == EFFECT_TERA_STARSTORM); } SINGLE_BATTLE_TEST("Tera Starstorm changes from Normal-type to Stellar-type if used by Terapagos-Stellar") { GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TERA_STARSTORM) == TYPE_NORMAL); PLAYER(SPECIES_TERAPAGOS_STELLAR); OPPONENT(SPECIES_MISDREAVUS); } WHEN { @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm changes from Normal-type to Stellar-type if u DOUBLE_BATTLE_TEST("Tera Starstorm targets both opponents in a double battle if used by Terapagos-Stellar") { GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].target == MOVE_TARGET_SELECTED); + ASSUME(GetMoveTarget(MOVE_TERA_STARSTORM) == MOVE_TARGET_SELECTED); PLAYER(SPECIES_TERAPAGOS_STELLAR); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -46,7 +46,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapa PARAMETRIZE { tera = GIMMICK_NONE; } PARAMETRIZE { tera = GIMMICK_TERA; } GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_TERA_STARSTORM) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_TERAPAGOS_STELLAR) { Attack(100); SpAttack(50); } OPPONENT(SPECIES_WOBBUFFET) { Defense(200); SpDefense(200); } } WHEN { @@ -63,7 +63,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapa SINGLE_BATTLE_TEST("Tera Starstorm remains Normal-type if used by Pokemon other than Terapagos") { GIVEN { - ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_TERA_STARSTORM) == TYPE_NORMAL); ASSUME(gSpeciesInfo[SPECIES_MISDREAVUS].types[0] == TYPE_GHOST); PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } OPPONENT(SPECIES_MISDREAVUS); diff --git a/test/battle/move_effect/thousand_arrows.c b/test/battle/move_effect/thousand_arrows.c index 09e726fa20..c62e71001d 100644 --- a/test/battle/move_effect/thousand_arrows.c +++ b/test/battle/move_effect/thousand_arrows.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(MoveHasAdditionalEffect(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN) == TRUE); - ASSUME(gMovesInfo[MOVE_THOUSAND_ARROWS].ignoreTypeIfFlyingAndUngrounded == TRUE); + ASSUME(MoveHasAdditionalEffect(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN)); + ASSUME(MoveIgnoresTypeIfFlyingAndUngrounded(MOVE_THOUSAND_ARROWS) == TRUE); } SINGLE_BATTLE_TEST("Thousand Arrows does not ground mons behind substitutes") diff --git a/test/battle/move_effect/thunder.c b/test/battle/move_effect/thunder.c index 98a4979e79..81ebd416ca 100644 --- a/test/battle/move_effect/thunder.c +++ b/test/battle/move_effect/thunder.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_THUNDER].effect == EFFECT_THUNDER); - ASSUME(gMovesInfo[MOVE_THUNDER].accuracy == 70); + ASSUME(GetMoveEffect(MOVE_THUNDER) == EFFECT_THUNDER); + ASSUME(GetMoveAccuracy(MOVE_THUNDER) == 70); } SINGLE_BATTLE_TEST("Thunder's accuracy is lowered to 50% in Sunlight") diff --git a/test/battle/move_effect/tidy_up.c b/test/battle/move_effect/tidy_up.c index fcb78ba962..9c934ab213 100644 --- a/test/battle/move_effect/tidy_up.c +++ b/test/battle/move_effect/tidy_up.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TIDY_UP].effect == EFFECT_TIDY_UP); + ASSUME(GetMoveEffect(MOVE_TIDY_UP) == EFFECT_TIDY_UP); } SINGLE_BATTLE_TEST("Tidy Up raises Attack and Speed by one") diff --git a/test/battle/move_effect/torment.c b/test/battle/move_effect/torment.c index dc911691b0..446d168de2 100644 --- a/test/battle/move_effect/torment.c +++ b/test/battle/move_effect/torment.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT); + ASSUME(GetMoveEffect(MOVE_TORMENT) == EFFECT_TORMENT); } SINGLE_BATTLE_TEST("Torment prevents consecutive move uses") diff --git a/test/battle/move_effect/toxic.c b/test/battle/move_effect/toxic.c index 804ed56b8f..7b8274a441 100644 --- a/test/battle/move_effect/toxic.c +++ b/test/battle/move_effect/toxic.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC); } SINGLE_BATTLE_TEST("Toxic inflicts bad poison") diff --git a/test/battle/move_effect/toxic_spikes.c b/test/battle/move_effect/toxic_spikes.c index fd18f57b97..70053b4a44 100644 --- a/test/battle/move_effect/toxic_spikes.c +++ b/test/battle/move_effect/toxic_spikes.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES); + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); } SINGLE_BATTLE_TEST("Toxic Spikes inflicts poison on switch in") @@ -212,7 +212,7 @@ SINGLE_BATTLE_TEST("Toxic Spikes are removed by Poison-type Pokémon affected by SINGLE_BATTLE_TEST("Toxic Spikes inflicts poison on switch in after Primal Reversed mon fainted") // Oddly specific, but encountered during testing { GIVEN { - ASSUME(gMovesInfo[MOVE_MEMENTO].effect == EFFECT_MEMENTO); // Faints the user. + ASSUME(GetMoveEffect(MOVE_MEMENTO) == EFFECT_MEMENTO); // Faints the user. PLAYER(SPECIES_WOBBUFFET) {Speed(5); } PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(1); } PLAYER(SPECIES_WYNAUT) {Speed(5); } diff --git a/test/battle/move_effect/triple_kick.c b/test/battle/move_effect/triple_kick.c index 9fe0ec6022..5aeb1ea442 100644 --- a/test/battle/move_effect/triple_kick.c +++ b/test/battle/move_effect/triple_kick.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].effect == EFFECT_TRIPLE_KICK); + ASSUME(GetMoveEffect(MOVE_TRIPLE_KICK) == EFFECT_TRIPLE_KICK); } SINGLE_BATTLE_TEST("Triple Kick damage is increased by its base damage for each hit") diff --git a/test/battle/move_effect/two_turns_attack.c b/test/battle/move_effect/two_turns_attack.c index efeb419ce5..200fc72d18 100644 --- a/test/battle/move_effect/two_turns_attack.c +++ b/test/battle/move_effect/two_turns_attack.c @@ -3,20 +3,14 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_RAZOR_WIND].effect == EFFECT_TWO_TURNS_ATTACK); - ASSUME(gMovesInfo[MOVE_SKULL_BASH].effect == EFFECT_TWO_TURNS_ATTACK); + ASSUME(GetMoveEffect(MOVE_RAZOR_WIND) == EFFECT_TWO_TURNS_ATTACK); + ASSUME(GetMoveEffect(MOVE_SKULL_BASH) == EFFECT_TWO_TURNS_ATTACK); ASSUME(MoveHasAdditionalEffectSelf(MOVE_SKULL_BASH, MOVE_EFFECT_DEF_PLUS_1) == TRUE); - ASSUME(gMovesInfo[MOVE_SKY_ATTACK].effect == EFFECT_TWO_TURNS_ATTACK); - - // Solar Beam - check for sun - ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].effect == EFFECT_SOLAR_BEAM); - ASSUME(HIHALF(gMovesInfo[MOVE_SOLAR_BLADE].argument) == B_WEATHER_SUN); - ASSUME(gMovesInfo[MOVE_SOLAR_BLADE].effect == EFFECT_SOLAR_BEAM); - ASSUME(HIHALF(gMovesInfo[MOVE_SOLAR_BLADE].argument) == B_WEATHER_SUN); + ASSUME(GetMoveEffect(MOVE_SKY_ATTACK) == EFFECT_TWO_TURNS_ATTACK); // Electro shot - check for rain - ASSUME(HIHALF(gMovesInfo[MOVE_ELECTRO_SHOT].argument) == B_WEATHER_RAIN); - ASSUME(gMovesInfo[MOVE_ELECTRO_SHOT].effect == EFFECT_TWO_TURNS_ATTACK); + ASSUME(GetMoveTwoTurnAttackWeather(MOVE_ELECTRO_SHOT) == B_WEATHER_RAIN); + ASSUME(GetMoveEffect(MOVE_ELECTRO_SHOT) == EFFECT_TWO_TURNS_ATTACK); ASSUME(MoveHasAdditionalEffectSelf(MOVE_ELECTRO_SHOT, MOVE_EFFECT_SP_ATK_PLUS_1) == TRUE); } diff --git a/test/battle/move_effect/upper_hand.c b/test/battle/move_effect/upper_hand.c index 69b2b75ef9..72a80a0542 100644 --- a/test/battle/move_effect/upper_hand.c +++ b/test/battle/move_effect/upper_hand.c @@ -3,16 +3,16 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_UPPER_HAND].effect == EFFECT_UPPER_HAND); - ASSUME(gMovesInfo[MOVE_UPPER_HAND].priority == 3); + ASSUME(GetMoveEffect(MOVE_UPPER_HAND) == EFFECT_UPPER_HAND); + ASSUME(GetMovePriority(MOVE_UPPER_HAND) == 3); ASSUME(MoveHasAdditionalEffect(MOVE_UPPER_HAND, MOVE_EFFECT_FLINCH) == TRUE); } SINGLE_BATTLE_TEST("Upper Hand succeeds if the target is using a priority attacking move and causes it to flinch") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].priority == 2); + ASSUME(GetMoveCategory(MOVE_EXTREME_SPEED) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMovePriority(MOVE_EXTREME_SPEED) == 2); PLAYER(SPECIES_MIENSHAO); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -28,8 +28,8 @@ SINGLE_BATTLE_TEST("Upper Hand succeeds if the target is using a priority attack SINGLE_BATTLE_TEST("Upper Hand fails if the target is using a status move") { GIVEN { - ASSUME(gMovesInfo[MOVE_BABY_DOLL_EYES].category == DAMAGE_CATEGORY_STATUS); - ASSUME(gMovesInfo[MOVE_BABY_DOLL_EYES].priority == 1); + ASSUME(GetMoveCategory(MOVE_BABY_DOLL_EYES) == DAMAGE_CATEGORY_STATUS); + ASSUME(GetMovePriority(MOVE_BABY_DOLL_EYES) == 1); PLAYER(SPECIES_MIENSHAO); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -47,8 +47,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target is using a status move") SINGLE_BATTLE_TEST("Upper Hand fails if the target is not using a priority move") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0); + ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0); PLAYER(SPECIES_MIENSHAO); OPPONENT(SPECIES_COMFEY) { Ability(ABILITY_FLOWER_VEIL); } } WHEN { @@ -66,8 +66,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target is not using a priority move" SINGLE_BATTLE_TEST("Upper Hand succeeds if the target's move is boosted in priority by an Ability") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0); + ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0); PLAYER(SPECIES_MIENSHAO) { Speed(10); } OPPONENT(SPECIES_COMFEY) { Speed(5); Ability(ABILITY_TRIAGE); } } WHEN { @@ -83,8 +83,8 @@ SINGLE_BATTLE_TEST("Upper Hand succeeds if the target's move is boosted in prior SINGLE_BATTLE_TEST("Upper Hand fails if the target moves first") { GIVEN { - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL); - ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0); + ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0); PLAYER(SPECIES_MIENSHAO) { Speed(5); } OPPONENT(SPECIES_COMFEY) { Speed(10); Ability(ABILITY_TRIAGE); } } WHEN { @@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target moves first") SINGLE_BATTLE_TEST("Upper Hand is boosted by Sheer Force") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].category == DAMAGE_CATEGORY_PHYSICAL); - ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].priority == 2); + ASSUME(GetMoveCategory(MOVE_EXTREME_SPEED) == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMovePriority(MOVE_EXTREME_SPEED) == 2); ASSUME(MoveIsAffectedBySheerForce(MOVE_UPPER_HAND) == TRUE); PLAYER(SPECIES_HARIYAMA) { Ability(ABILITY_SHEER_FORCE); } OPPONENT(SPECIES_WOBBUFFET); @@ -124,7 +124,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use Upper Hand unless it has seen a priority mov PARAMETRIZE { move = MOVE_QUICK_ATTACK; } GIVEN { AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); - ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1); PLAYER(SPECIES_WOBBUFFET) {Moves(move); } OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_UPPER_HAND, MOVE_KARATE_CHOP); } } WHEN { diff --git a/test/battle/move_effect/uproar.c b/test/battle/move_effect/uproar.c index a97422390f..cbe17ce066 100644 --- a/test/battle/move_effect/uproar.c +++ b/test/battle/move_effect/uproar.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_UPROAR].effect == EFFECT_UPROAR); + ASSUME(GetMoveEffect(MOVE_UPROAR) == EFFECT_UPROAR); } DOUBLE_BATTLE_TEST("Uproar status causes sleeping pokemon to wake up during an attack") diff --git a/test/battle/move_effect/wake_up_slap.c b/test/battle/move_effect/wake_up_slap.c index 0a881be100..0e172bf053 100644 --- a/test/battle/move_effect/wake_up_slap.c +++ b/test/battle/move_effect/wake_up_slap.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_WAKE_UP_SLAP, MOVE_EFFECT_REMOVE_STATUS) == TRUE); - ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].argument == STATUS1_SLEEP); + ASSUME(GetMoveEffectArg_Status(MOVE_WAKE_UP_SLAP) == STATUS1_SLEEP); } SINGLE_BATTLE_TEST("Wake-Up Slap does not cure paralyzed pokemons behind substitutes or get increased power") diff --git a/test/battle/move_effect/weather_ball.c b/test/battle/move_effect/weather_ball.c index 432e5f79f7..0474383483 100644 --- a/test/battle/move_effect/weather_ball.c +++ b/test/battle/move_effect/weather_ball.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL); + ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL); } SINGLE_BATTLE_TEST("Weather Ball doubles its power and turns to a Fire-type move in Sunlight", s16 damage) diff --git a/test/battle/move_effect/worry_seed.c b/test/battle/move_effect/worry_seed.c index 3e74c883e7..c4b18b7cab 100644 --- a/test/battle/move_effect/worry_seed.c +++ b/test/battle/move_effect/worry_seed.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED); + ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED); } SINGLE_BATTLE_TEST("Worry Seed replaces target's ability with Insomnia") diff --git a/test/battle/move_effect_secondary/bug_bite.c b/test/battle/move_effect_secondary/bug_bite.c index fdf9b05cf4..e086941a5e 100644 --- a/test/battle/move_effect_secondary/bug_bite.c +++ b/test/battle/move_effect_secondary/bug_bite.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE)); - ASSUME(gMovesInfo[MOVE_BUG_BITE].pp == 20); + ASSUME(GetMovePP(MOVE_BUG_BITE) == 20); } // Pretty much copy/paste of the Berry Fling Test. diff --git a/test/battle/move_effect_secondary/burn.c b/test/battle/move_effect_secondary/burn.c index 9801ad1f25..0bc979f08e 100644 --- a/test/battle/move_effect_secondary/burn.c +++ b/test/battle/move_effect_secondary/burn.c @@ -43,7 +43,7 @@ DOUBLE_BATTLE_TEST("Lava Plume inflicts burn to all adjacent battlers") { GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_LAVA_PLUME, MOVE_EFFECT_BURN) == TRUE); - ASSUME(gMovesInfo[MOVE_LAVA_PLUME].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_LAVA_PLUME) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Scald shouldn't burn a Water-type Pokémon") GIVEN { ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER); ASSUME(MoveHasAdditionalEffect(MOVE_SCALD, MOVE_EFFECT_BURN) == TRUE); - ASSUME(gMovesInfo[MOVE_SCALD].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_SCALD) == TYPE_WATER); PLAYER(SPECIES_SQUIRTLE); OPPONENT(SPECIES_SQUIRTLE); } WHEN { diff --git a/test/battle/move_effect_secondary/freeze.c b/test/battle/move_effect_secondary/freeze.c index 45005cf5d7..bfaadcebe1 100644 --- a/test/battle/move_effect_secondary/freeze.c +++ b/test/battle/move_effect_secondary/freeze.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE); - ASSUME(gMovesInfo[MOVE_BLIZZARD].accuracy == 70); + ASSUME(GetMoveAccuracy(MOVE_BLIZZARD) == 70); } #if B_USE_FROSTBITE == TRUE @@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("Freezing Glare shouldn't freeze Psychic-types") GIVEN { ASSUME(gSpeciesInfo[SPECIES_ARTICUNO_GALAR].types[0] == TYPE_PSYCHIC); ASSUME(MoveHasAdditionalEffect(MOVE_FREEZING_GLARE, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE); - ASSUME(gMovesInfo[MOVE_FREEZING_GLARE].type == TYPE_PSYCHIC); + ASSUME(GetMoveType(MOVE_FREEZING_GLARE) == TYPE_PSYCHIC); PLAYER(SPECIES_ARTICUNO_GALAR); OPPONENT(SPECIES_ARTICUNO_GALAR); } WHEN { diff --git a/test/battle/move_effect_secondary/haze.c b/test/battle/move_effect_secondary/haze.c new file mode 100644 index 0000000000..c3831f0768 --- /dev/null +++ b/test/battle/move_effect_secondary/haze.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_FREEZY_FROST, MOVE_EFFECT_HAZE) == TRUE); +} + +SINGLE_BATTLE_TEST("Freeze Frost restores stat changes when it was succesful") +{ + bool32 moveSuccess; + PARAMETRIZE { moveSuccess = FALSE; } + PARAMETRIZE { moveSuccess = TRUE; } + + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FREEZY_FROST, hit: moveSuccess); } + } SCENE { + if (moveSuccess == TRUE) + { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player); + MESSAGE("All stat changes were eliminated!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player); + MESSAGE("All stat changes were eliminated!"); + } + } + } +} diff --git a/test/battle/move_effect/plasma_fists.c b/test/battle/move_effect_secondary/ion_deluge.c similarity index 79% rename from test/battle/move_effect/plasma_fists.c rename to test/battle/move_effect_secondary/ion_deluge.c index 93c8869026..e5bf7c0810 100644 --- a/test/battle/move_effect/plasma_fists.c +++ b/test/battle/move_effect_secondary/ion_deluge.c @@ -3,13 +3,13 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_PLASMA_FISTS].effect == EFFECT_PLASMA_FISTS); + ASSUME(MoveHasAdditionalEffect(MOVE_PLASMA_FISTS, MOVE_EFFECT_ION_DELUGE) == TRUE); } SINGLE_BATTLE_TEST("Ion Duldge turns normal moves into electric for the remainder of the current turn") { GIVEN { - ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE); + ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE); PLAYER(SPECIES_KRABBY); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -47,6 +47,26 @@ SINGLE_BATTLE_TEST("Plasma Fists turns normal moves into electric for the remain } } +SINGLE_BATTLE_TEST("Plasma Fists does not set up Ion Deluge if it does not connect") +{ + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_PHANPY].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_PHANPY].types[1] == TYPE_GROUND); + PLAYER(SPECIES_KRABBY); + OPPONENT(SPECIES_PHANPY); + } WHEN { + TURN { MOVE(player, MOVE_PLASMA_FISTS); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + MESSAGE("Krabby used Plasma Fists!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PLASMA_FISTS, player); + MESSAGE("A deluge of ions showers the battlefield!"); + } + MESSAGE("The opposing Phanpy used Tackle!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + NOT MESSAGE("It's super effective!"); + } +} + SINGLE_BATTLE_TEST("Plasma Fists type-changing effect does not override Pixilate") { GIVEN { diff --git a/test/battle/move_effect_secondary/leech_seed.c b/test/battle/move_effect_secondary/leech_seed.c new file mode 100644 index 0000000000..c5a8db57cc --- /dev/null +++ b/test/battle/move_effect_secondary/leech_seed.c @@ -0,0 +1,37 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_SAPPY_SEED, MOVE_EFFECT_LEECH_SEED) == TRUE); +} + +SINGLE_BATTLE_TEST("Sappy Seed can seed the target") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SAPPY_SEED); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player); + MESSAGE("The opposing Wobbuffet was seeded!"); + MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!"); + } +} + +SINGLE_BATTLE_TEST("Sappy Seed is not going to seed the target if it fails") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SAPPY_SEED, hit: FALSE); } + } SCENE { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player); + MESSAGE("The opposing Wobbuffet was seeded!"); + MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!"); + } + } +} diff --git a/test/battle/move_effect_secondary/light_screen.c b/test/battle/move_effect_secondary/light_screen.c new file mode 100644 index 0000000000..244e469893 --- /dev/null +++ b/test/battle/move_effect_secondary/light_screen.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_GLITZY_GLOW, MOVE_EFFECT_LIGHT_SCREEN) == TRUE); +} + +SINGLE_BATTLE_TEST("Glitzy Glow sets up Light Screen when it was succesful") +{ + bool32 moveSuccess; + PARAMETRIZE { moveSuccess = FALSE; } + PARAMETRIZE { moveSuccess = TRUE; } + + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_GLITZY_GLOW, hit: moveSuccess); } + } SCENE { + if (moveSuccess == TRUE) + { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player); + MESSAGE("Light Screen made your team stronger against special moves!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player); + MESSAGE("Light Screen made your team stronger against special moves!"); + } + } + } +} diff --git a/test/battle/move_effect_secondary/order_up.c b/test/battle/move_effect_secondary/order_up.c index 8d286850a2..ec6f1c51b5 100644 --- a/test/battle/move_effect_secondary/order_up.c +++ b/test/battle/move_effect_secondary/order_up.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_ORDER_UP].additionalEffects[0].moveEffect == MOVE_EFFECT_ORDER_UP); + ASSUME(GetMoveAdditionalEffectById(MOVE_ORDER_UP, 0)->moveEffect == MOVE_EFFECT_ORDER_UP); } DOUBLE_BATTLE_TEST("Order Up increases a stat based on Tatsugiri's form") @@ -123,7 +123,7 @@ DOUBLE_BATTLE_TEST("Order up does not boosts any stats if Dondozo is not affecte DOUBLE_BATTLE_TEST("Order Up is boosted by Sheer Force without removing the stat boosting effect") { GIVEN { - ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT); + ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT); PLAYER(SPECIES_DONDOZO) { Speed(10); } PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); } OPPONENT(SPECIES_WOBBUFFET) { Speed(8); } @@ -146,8 +146,8 @@ DOUBLE_BATTLE_TEST("Order Up is always boosted by Sheer Force", s16 damage) PARAMETRIZE(move = MOVE_ENTRAINMENT, ability = ABILITY_COMMANDER); GIVEN { - ASSUME(gMovesInfo[MOVE_HAZE].effect == EFFECT_HAZE); - ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT); + ASSUME(GetMoveEffect(MOVE_HAZE) == EFFECT_HAZE); + ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT); PLAYER(SPECIES_DONDOZO) { Speed(10); } PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); Ability(ability); } OPPONENT(SPECIES_TAUROS) { Speed(21); Ability(ABILITY_SHEER_FORCE); } diff --git a/test/battle/move_effect_secondary/paralysis.c b/test/battle/move_effect_secondary/paralysis.c index 0e9d9589a8..711ca11ee8 100644 --- a/test/battle/move_effect_secondary/paralysis.c +++ b/test/battle/move_effect_secondary/paralysis.c @@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Body Slam shouldn't paralyze Normal-types") GIVEN { ASSUME(gSpeciesInfo[SPECIES_TAUROS].types[0] == TYPE_NORMAL); ASSUME(MoveHasAdditionalEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE); - ASSUME(gMovesInfo[MOVE_BODY_SLAM].type == TYPE_NORMAL); + ASSUME(GetMoveType(MOVE_BODY_SLAM) == TYPE_NORMAL); PLAYER(SPECIES_TAUROS); OPPONENT(SPECIES_TAUROS); } WHEN { diff --git a/test/battle/move_effect_secondary/psychic_noise.c b/test/battle/move_effect_secondary/psychic_noise.c index e44ae75abe..8e5eae4efb 100644 --- a/test/battle/move_effect_secondary/psychic_noise.c +++ b/test/battle/move_effect_secondary/psychic_noise.c @@ -4,7 +4,7 @@ ASSUMPTIONS { ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE)); - ASSUME(gMovesInfo[MOVE_RECOVER].effect == EFFECT_RESTORE_HP); + ASSUME(GetMoveEffect(MOVE_RECOVER) == EFFECT_RESTORE_HP); } SINGLE_BATTLE_TEST("Psychic Noise blocks healing moves for 2 turns") diff --git a/test/battle/move_effect_secondary/reflect.c b/test/battle/move_effect_secondary/reflect.c new file mode 100644 index 0000000000..6a0dda06d8 --- /dev/null +++ b/test/battle/move_effect_secondary/reflect.c @@ -0,0 +1,32 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_BADDY_BAD, MOVE_EFFECT_REFLECT) == TRUE); +} + +SINGLE_BATTLE_TEST("Baddy Bad sets up Reflect when it was succesful") +{ + bool32 moveSuccess; + PARAMETRIZE { moveSuccess = FALSE; } + PARAMETRIZE { moveSuccess = TRUE; } + + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BADDY_BAD, hit: moveSuccess); } + } SCENE { + if (moveSuccess == TRUE) + { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player); + MESSAGE("Reflect made your team stronger against physical moves!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player); + MESSAGE("Reflect made your team stronger against physical moves!"); + } + } + } +} diff --git a/test/battle/move_effects_combined/axe_kick.c b/test/battle/move_effects_combined/axe_kick.c index 94ab9377ad..5cc5b9b90c 100644 --- a/test/battle/move_effects_combined/axe_kick.c +++ b/test/battle/move_effects_combined/axe_kick.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_AXE_KICK].effect == EFFECT_RECOIL_IF_MISS); + ASSUME(GetMoveEffect(MOVE_AXE_KICK) == EFFECT_RECOIL_IF_MISS); ASSUME(MoveHasAdditionalEffect(MOVE_AXE_KICK, MOVE_EFFECT_CONFUSION) == TRUE); } diff --git a/test/battle/move_effects_combined/barb_barrage.c b/test/battle/move_effects_combined/barb_barrage.c index e2e5059fee..62f78cd4cf 100644 --- a/test/battle/move_effects_combined/barb_barrage.c +++ b/test/battle/move_effects_combined/barb_barrage.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].argument == STATUS1_PSN_ANY); + ASSUME(GetMoveEffect(MOVE_BARB_BARRAGE) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_BARB_BARRAGE) == STATUS1_PSN_ANY); ASSUME(MoveHasAdditionalEffect(MOVE_BARB_BARRAGE, MOVE_EFFECT_POISON) == TRUE); } diff --git a/test/battle/move_effects_combined/hurricane.c b/test/battle/move_effects_combined/hurricane.c index 61acac6649..02620f4d05 100644 --- a/test/battle/move_effects_combined/hurricane.c +++ b/test/battle/move_effects_combined/hurricane.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_HURRICANE].effect == EFFECT_THUNDER); - ASSUME(gMovesInfo[MOVE_HURRICANE].accuracy == 70); + ASSUME(GetMoveEffect(MOVE_HURRICANE) == EFFECT_THUNDER); + ASSUME(GetMoveAccuracy(MOVE_HURRICANE) == 70); } SINGLE_BATTLE_TEST("Hurricane's accuracy is lowered to 50% in Sunlight") @@ -39,10 +39,10 @@ SINGLE_BATTLE_TEST("Hurricane can hit airborne targets (Fly, Bounce)") PARAMETRIZE { move = MOVE_FLY; } PARAMETRIZE { move = MOVE_BOUNCE; } GIVEN { - ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_FLY].argument)) == STATUS3_ON_AIR); - ASSUME(gMovesInfo[MOVE_BOUNCE].effect == EFFECT_SEMI_INVULNERABLE); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_BOUNCE].argument)) == STATUS3_ON_AIR); + ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR); + ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(move); } } WHEN { @@ -57,8 +57,8 @@ SINGLE_BATTLE_TEST("Hurricane can hit airborne targets (Fly, Bounce)") DOUBLE_BATTLE_TEST("Hurricane can hit airborne targets (Sky Drop)") { GIVEN { - ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP); - ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_SKY_DROP].argument)) == STATUS3_ON_AIR); + ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP); + ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SKY_DROP) == STATUS3_ON_AIR); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effects_combined/infernal_parade.c b/test/battle/move_effects_combined/infernal_parade.c index 6aa46ef8cb..266718d2e9 100644 --- a/test/battle/move_effects_combined/infernal_parade.c +++ b/test/battle/move_effects_combined/infernal_parade.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_INFERNAL_PARADE].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); - ASSUME(gMovesInfo[MOVE_INFERNAL_PARADE].argument == STATUS1_ANY); + ASSUME(GetMoveEffect(MOVE_INFERNAL_PARADE) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS); + ASSUME(GetMoveEffectArg_Status(MOVE_INFERNAL_PARADE) == STATUS1_ANY); ASSUME(MoveHasAdditionalEffect(MOVE_INFERNAL_PARADE, MOVE_EFFECT_BURN) == TRUE); } diff --git a/test/battle/move_effects_combined/make_it_rain.c b/test/battle/move_effects_combined/make_it_rain.c index 5469eac8a5..e9c8b153ce 100644 --- a/test/battle/move_effects_combined/make_it_rain.c +++ b/test/battle/move_effects_combined/make_it_rain.c @@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Make It Rain lowers special attack by one stage") s16 damage[2]; GIVEN { - ASSUME(gMovesInfo[MOVE_MAKE_IT_RAIN].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_MAKE_IT_RAIN) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_effects_combined/triple_arrows.c b/test/battle/move_effects_combined/triple_arrows.c index ad7878fdc9..4fd040e32a 100644 --- a/test/battle/move_effects_combined/triple_arrows.c +++ b/test/battle/move_effects_combined/triple_arrows.c @@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Triple Arrows lands a critical hit") PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT); GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_7); - ASSUME(gMovesInfo[MOVE_TRIPLE_ARROWS].criticalHitStage == 1); + ASSUME(GetMoveCriticalHitStage(MOVE_TRIPLE_ARROWS) == 1); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_flags/cant_use_twice.c b/test/battle/move_flags/cant_use_twice.c index 99bd681acb..cba5596d26 100644 --- a/test/battle/move_flags/cant_use_twice.c +++ b/test/battle/move_flags/cant_use_twice.c @@ -3,8 +3,8 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_GIGATON_HAMMER].cantUseTwice == TRUE); - ASSUME(gMovesInfo[MOVE_BLOOD_MOON].cantUseTwice == TRUE); + ASSUME(MoveCantBeUsedTwice(MOVE_GIGATON_HAMMER) == TRUE); + ASSUME(MoveCantBeUsedTwice(MOVE_BLOOD_MOON) == TRUE); } SINGLE_BATTLE_TEST("Struggle will be used if slow Encore is used on moves with the cantUseTwice flag") @@ -13,7 +13,7 @@ SINGLE_BATTLE_TEST("Struggle will be used if slow Encore is used on moves with t PARAMETRIZE { move = MOVE_GIGATON_HAMMER; } PARAMETRIZE { move = MOVE_BLOOD_MOON; } GIVEN { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("Moves with the cantUseTwice flag strike again if fast encore PARAMETRIZE { move = MOVE_GIGATON_HAMMER; } PARAMETRIZE { move = MOVE_BLOOD_MOON; } GIVEN { - ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); + ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/move_flags/damages_airborne_double_damage.c b/test/battle/move_flags/damages_airborne_double_damage.c index dcdb801ff6..adeac7d3a2 100644 --- a/test/battle/move_flags/damages_airborne_double_damage.c +++ b/test/battle/move_flags/damages_airborne_double_damage.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being airborne causes the target to take double damage from PARAMETRIZE { useDive = FALSE; } PARAMETRIZE { useDive = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TWISTER].damagesAirborneDoubleDamage); + ASSUME(MoveDamagesAirborneDoubleDamage(MOVE_TWISTER)); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } } WHEN { diff --git a/test/battle/move_flags/damages_underground.c b/test/battle/move_flags/damages_underground.c index 97b792b4dd..7d4b8cd946 100644 --- a/test/battle/move_flags/damages_underground.c +++ b/test/battle/move_flags/damages_underground.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being underground causes the target to take double damage fr PARAMETRIZE { useDig = FALSE; } PARAMETRIZE { useDig = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].damagesUnderground); + ASSUME(MoveDamagesUnderground(MOVE_EARTHQUAKE)); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } } WHEN { diff --git a/test/battle/move_flags/damages_underwater.c b/test/battle/move_flags/damages_underwater.c index a7269a0162..b313d044c2 100644 --- a/test/battle/move_flags/damages_underwater.c +++ b/test/battle/move_flags/damages_underwater.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being underwater causes the target to take double damage fro PARAMETRIZE { useDive = FALSE; } PARAMETRIZE { useDive = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SURF].damagesUnderwater); + ASSUME(MoveDamagesUnderWater(MOVE_SURF)); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } } WHEN { diff --git a/test/battle/move_flags/ignores_target_ability.c b/test/battle/move_flags/ignores_target_ability.c index 2836f4838e..f4f9ff30a7 100644 --- a/test/battle/move_flags/ignores_target_ability.c +++ b/test/battle/move_flags/ignores_target_ability.c @@ -3,9 +3,9 @@ ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SUNSTEEL_STRIKE].ignoresTargetAbility); - ASSUME(gMovesInfo[MOVE_MOONGEIST_BEAM].ignoresTargetAbility); - ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].ignoresTargetAbility); + ASSUME(MoveIgnoresTargetAbility(MOVE_SUNSTEEL_STRIKE)); + ASSUME(MoveIgnoresTargetAbility(MOVE_MOONGEIST_BEAM)); + ASSUME(MoveIgnoresTargetAbility(MOVE_PHOTON_GEYSER)); } SINGLE_BATTLE_TEST("ignoresTargetAbility moves do not ignore the attacker's own ability", s16 damage) @@ -20,19 +20,19 @@ SINGLE_BATTLE_TEST("ignoresTargetAbility moves do not ignore the attacker's own PARAMETRIZE { move = MOVE_PHOTON_GEYSER; ability = ABILITY_UNAWARE; } ASSUME(gAbilitiesInfo[ABILITY_UNAWARE].breakable); - ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2); - ASSUME(gMovesInfo[MOVE_AMNESIA].effect == EFFECT_SPECIAL_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_AMNESIA) == EFFECT_SPECIAL_DEFENSE_UP_2); GIVEN { PLAYER(SPECIES_CLEFABLE) { Speed(1); Ability(ability); } OPPONENT(SPECIES_ARON) { Speed(2); } } WHEN { - if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL) + if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL) TURN { MOVE(opponent, MOVE_IRON_DEFENSE); MOVE(player, move); } else TURN { MOVE(opponent, MOVE_AMNESIA); MOVE(player, move); } } SCENE { - if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL) + if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL) ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, opponent); else ANIMATION(ANIM_TYPE_MOVE, MOVE_AMNESIA, opponent); diff --git a/test/battle/move_flags/minimize_double_damage.c b/test/battle/move_flags/minimize_double_damage.c index f3cdd7657f..fd44077c4f 100644 --- a/test/battle/move_flags/minimize_double_damage.c +++ b/test/battle/move_flags/minimize_double_damage.c @@ -7,8 +7,8 @@ SINGLE_BATTLE_TEST("MinimizeDoubleDamage flag makes moves cause double damage to PARAMETRIZE { useMinimize = FALSE; } PARAMETRIZE { useMinimize = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE); - ASSUME(gMovesInfo[MOVE_STEAMROLLER].minimizeDoubleDamage); + ASSUME(GetMoveEffect(MOVE_MINIMIZE) == EFFECT_MINIMIZE); + ASSUME(MoveIncreasesPowerToMinimizedTargets(MOVE_STEAMROLLER)); PLAYER(SPECIES_WOBBUFFET) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } } WHEN { diff --git a/test/battle/move_flags/powder.c b/test/battle/move_flags/powder.c index 35a6e1012b..04920f79f3 100644 --- a/test/battle/move_flags/powder.c +++ b/test/battle/move_flags/powder.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Powder moves are blocked by Grass-type Pokémon") { GIVEN { - ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove); + ASSUME(IsPowderMove(MOVE_STUN_SPORE)); ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ODDISH); diff --git a/test/battle/move_flags/recoil.c b/test/battle/move_flags/recoil.c index bdada8a114..dede6289da 100644 --- a/test/battle/move_flags/recoil.c +++ b/test/battle/move_flags/recoil.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Take Down deals 25% of recoil damage to the user") s16 recoilDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil == 25); + ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) == 25); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -27,7 +27,7 @@ SINGLE_BATTLE_TEST("Double Edge deals 33% of recoil damage to the user") s16 recoilDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil == 33); + ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) == 33); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Head Smash deals 50% of recoil damage to the user") s16 recoilDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_HEAD_SMASH].recoil == 50); + ASSUME(GetMoveRecoil(MOVE_HEAD_SMASH) == 50); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can b s16 recoilDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].recoil == 33); + ASSUME(GetMoveRecoil(MOVE_FLARE_BLITZ) == 33); ASSUME(MoveHasAdditionalEffect(MOVE_FLARE_BLITZ, MOVE_EFFECT_BURN)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_flags/strike_count.c b/test/battle/move_flags/strike_count.c index ba71e35c26..80a6f24359 100644 --- a/test/battle/move_flags/strike_count.c +++ b/test/battle/move_flags/strike_count.c @@ -4,7 +4,7 @@ SINGLE_BATTLE_TEST("Two strike count turns a move into a 2-hit move") { GIVEN { - ASSUME(gMovesInfo[MOVE_DOUBLE_KICK].strikeCount == 2); + ASSUME(GetMoveStrikeCount(MOVE_DOUBLE_KICK) == 2); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Three strike count turns a move into a 3-hit move") s16 thirdHit; GIVEN { - ASSUME(gMovesInfo[MOVE_TRIPLE_DIVE].strikeCount == 3); + ASSUME(GetMoveStrikeCount(MOVE_TRIPLE_DIVE) == 3); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -49,8 +49,8 @@ SINGLE_BATTLE_TEST("Surging Strikes hits 3 times with each hit being a critical s16 thirdHit; GIVEN { - ASSUME(gMovesInfo[MOVE_SURGING_STRIKES].strikeCount == 3); - ASSUME(gMovesInfo[MOVE_SURGING_STRIKES].alwaysCriticalHit == TRUE); + ASSUME(GetMoveStrikeCount(MOVE_SURGING_STRIKES) == 3); + ASSUME(MoveAlwaysCrits(MOVE_SURGING_STRIKES)); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index c8393685b8..a5f28f4f22 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -5,7 +5,7 @@ AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep cla { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -21,7 +21,7 @@ AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep cla { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -39,7 +39,7 @@ AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep move if partner is al { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active") { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -82,7 +82,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active ( { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } @@ -108,8 +108,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause") { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -128,8 +128,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause (Doubles)" { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } @@ -150,8 +150,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is ac { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -174,8 +174,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is ac { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); } @@ -196,9 +196,9 @@ SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clau { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); - ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT); PLAYER(SPECIES_WOBBUFFET) PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); } OPPONENT(SPECIES_WOBBUFFET); @@ -215,16 +215,16 @@ SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clau STATUS_ICON(opponent, sleep: TRUE); } MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!"); - } + } } SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will activate sleep clause") { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); - ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT); PLAYER(SPECIES_ZIGZAGOON) PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); } @@ -245,14 +245,14 @@ SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will activate sleep cla STATUS_ICON(opponent, sleep: TRUE); } MESSAGE("Sleep Clause kept Zigzagoon awake!"); - } + } } AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use Yawn while sleep clause is active") { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -269,7 +269,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Yawn will fail when sleep clause is active") { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -297,8 +297,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } @@ -321,8 +321,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } @@ -348,8 +348,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate slee GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } @@ -375,8 +375,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate slee GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(MoveMakesContact(MOVE_TACKLE)); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } @@ -401,7 +401,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will activate s GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -429,7 +429,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will still do d GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP)); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -456,7 +456,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Dire Claw cannot sleep a mon when sleep clause GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(MoveHasAdditionalEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW)); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -482,7 +482,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Dark Void can only sleep one opposing mon if s // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID); PLAYER(SPECIES_DARKRAI); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -507,7 +507,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: G-Max Befuddle can only sleep one opposing mon { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_G_MAX_BEFUDDLE].argument == MAX_EFFECT_EFFECT_SPORE_FOES); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_BEFUDDLE) == MAX_EFFECT_EFFECT_SPORE_FOES); PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_CATERPIE); OPPONENT(SPECIES_WOBBUFFET); @@ -532,7 +532,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(B_SLEEP_TURNS >= GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -564,10 +564,10 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { move = MOVE_SPARKLY_SWIRL; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); - ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL); - ASSUME(gMovesInfo[MOVE_SPARKLY_SWIRL].effect == EFFECT_SPARKLY_SWIRL); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_SPARKLY_SWIRL) == EFFECT_SPARKLY_SWIRL); ASSUME(B_SLEEP_TURNS >= GEN_5); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -622,7 +622,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(MoveHasAdditionalEffect(MOVE_WAKE_UP_SLAP, MOVE_EFFECT_REMOVE_STATUS)); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -664,8 +664,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_UPROAR].effect == EFFECT_UPROAR); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_UPROAR) == EFFECT_UPROAR); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -682,7 +682,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo STATUS_ICON(opponentLeft, sleep: TRUE); MESSAGE("Zigzagoon used Uproar!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_UPROAR, playerRight); - MESSAGE("Zigzagoon caused an uproar!"); + MESSAGE("Zigzagoon caused an uproar!"); MESSAGE("The uproar woke the opposing Zigzagoon!"); STATUS_ICON(opponentLeft, sleep: FALSE); MESSAGE("The opposing Zigzagoon used Roar!"); @@ -705,14 +705,14 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { move = MOVE_AROMATHERAPY; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); - ASSUME(gMovesInfo[MOVE_PSYCHO_SHIFT].effect == EFFECT_PSYCHO_SHIFT); - ASSUME(gMovesInfo[MOVE_JUNGLE_HEALING].effect == EFFECT_JUNGLE_HEALING); - ASSUME(gMovesInfo[MOVE_LUNAR_BLESSING].effect == EFFECT_JUNGLE_HEALING); - ASSUME(gMovesInfo[MOVE_PURIFY].effect == EFFECT_PURIFY); - ASSUME(gMovesInfo[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART); - ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK); + ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT); + ASSUME(GetMoveEffect(MOVE_JUNGLE_HEALING) == EFFECT_JUNGLE_HEALING); + ASSUME(GetMoveEffect(MOVE_LUNAR_BLESSING) == EFFECT_JUNGLE_HEALING); + ASSUME(GetMoveEffect(MOVE_PURIFY) == EFFECT_PURIFY); + ASSUME(GetMoveEffect(MOVE_TAKE_HEART) == EFFECT_TAKE_HEART); + ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); PLAYER(SPECIES_ZIGZAGOON) { Item(ITEM_CHESTO_BERRY); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, move); } @@ -761,7 +761,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_PELIPPER) { Ability(ABILITY_DRIZZLE); } OPPONENT(SPECIES_LUVDISC) { Ability(ABILITY_HYDRATION); } } WHEN { @@ -785,7 +785,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_SWABLU) { Ability(ABILITY_NATURAL_CURE); } OPPONENT(SPECIES_ZIGZAGOON); @@ -815,7 +815,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PASSES_RANDOMLY(33, 100, RNG_SHED_SKIN); GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_DRATINI) { Ability(ABILITY_SHED_SKIN); } } WHEN { @@ -839,7 +839,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PASSES_RANDOMLY(30, 100, RNG_HEALER); GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -867,7 +867,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { heldItem = ITEM_LUM_BERRY; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); PLAYER(SPECIES_ZIGZAGOON); @@ -898,8 +898,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { heldItem = ITEM_LUM_BERRY; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS); PLAYER(SPECIES_ZIGZAGOON); @@ -931,7 +931,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(gItemsInfo[ITEM_AWAKENING].battleUsage == EFFECT_ITEM_CURE_STATUS); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -955,7 +955,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON) { Level(5); } OPPONENT(SPECIES_ZIGZAGOON); @@ -980,7 +980,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON) { Level(5); } @@ -1008,7 +1008,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { ability = ABILITY_INSOMNIA; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_DELIBIRD) { Ability(ability); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_SKILL_SWAP); } } WHEN { @@ -1044,7 +1044,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo PARAMETRIZE { ability = ABILITY_INSOMNIA; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON) PLAYER(SPECIES_DELIBIRD) { Ability(ability); } OPPONENT(SPECIES_RALTS) { Ability(ABILITY_TRACE); } @@ -1081,7 +1081,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo KNOWN_FAILING; // Sleep Clause parts work, but Imposter seems broken with battle messages / targeting. Issue #5565 https://github.com/rh-hideout/pokeemerald-expansion/issues/5565 GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL); PLAYER(SPECIES_ZIGZAGOON) PLAYER(SPECIES_DELIBIRD) { Ability(ability); } @@ -1116,7 +1116,7 @@ AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will use sleep moves again when sleep cl { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHESTO_BERRY); } @@ -1131,8 +1131,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_G_MAX_SWEETNESS].argument == MAX_EFFECT_AROMATHERAPY); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SWEETNESS) == MAX_EFFECT_AROMATHERAPY); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_APPLETUN) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1159,7 +1159,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Pre-existing sleep condition doesn't activate { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON) { Status1(STATUS1_SLEEP); } OPPONENT(SPECIES_ZIGZAGOON); @@ -1179,9 +1179,9 @@ SINGLE_BATTLE_TEST("Sleep Clause: Sleep caused by Effect Spore does not prevent GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -1215,8 +1215,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivat GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } @@ -1252,9 +1252,9 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivat GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -1292,8 +1292,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); } PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1328,8 +1328,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST); PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); } PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -1366,7 +1366,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Suppressing and then sleeping Vital Spirit / I PARAMETRIZE { ability = ABILITY_INSOMNIA; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_DELIBIRD) { Ability(ability); } OPPONENT(SPECIES_ZIGZAGOON); @@ -1397,7 +1397,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Mold Breaker Pokémon sleeping Vital Spirit / PARAMETRIZE { ability = ABILITY_INSOMNIA; } GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_PANCHAM) { Ability(ABILITY_MOLD_BREAKER); } OPPONENT(SPECIES_DELIBIRD) { Ability(ability); } OPPONENT(SPECIES_ZIGZAGOON); @@ -1424,9 +1424,9 @@ SINGLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon slept due to Effect Spore befo PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE); GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); - ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); + ASSUME(MoveMakesContact(MOVE_TACKLE)); PLAYER(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); } OPPONENT(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1451,8 +1451,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon who's partner is slept before { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1467,7 +1467,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon who's partner is slept before ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft); MESSAGE("The opposing Zigzagoon fell asleep!"); STATUS_ICON(opponentLeft, sleep: TRUE); - NONE_OF { + NONE_OF { MESSAGE( "The opposing Zigzagoon fell asleep!"); STATUS_ICON(opponentRight, sleep: TRUE); } @@ -1478,8 +1478,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: If both Pokémon on one side are Yawn'd at the { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_ZIGZAGOON) { Speed(5); } PLAYER(SPECIES_ZIGZAGOON) { Speed(4); } OPPONENT(SPECIES_ZIGZAGOON) { Speed(3); } @@ -1503,8 +1503,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) fail if slee { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1528,8 +1528,8 @@ SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1558,8 +1558,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT); - ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT); + ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_DARKRAI); @@ -1583,7 +1583,7 @@ SINGLE_BATTLE_TEST("Sleep Clause: Magic Bounce'ing a sleep move activates sleep { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); @@ -1612,7 +1612,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Magic Bounce reflecting Dark Void only sleeps // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move) GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_DARK_VOID].effect == EFFECT_DARK_VOID); + ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID); PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_DARKRAI); @@ -1636,15 +1636,15 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your pa { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); - PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); - OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); } WHEN { TURN { MOVE(playerLeft, MOVE_SPORE, target: playerRight); } TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_SPORE, target: playerRight); } @@ -1679,15 +1679,15 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your pa { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); + PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); - PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); OPPONENT(SPECIES_ZIGZAGOON); - OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); } WHEN { TURN { MOVE(playerLeft, MOVE_YAWN, target: playerRight); } TURN {} @@ -1722,7 +1722,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves used after being Encore'd are prev { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -1751,8 +1751,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Spore'ing opponent after Yawn'ing partner does { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); @@ -1788,8 +1788,8 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Opponent Spore'ing player's partner after part { GIVEN { FLAG_SET(B_FLAG_SLEEP_CLAUSE); - ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); - ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); + ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); diff --git a/test/battle/spread_moves.c b/test/battle/spread_moves.c index 5228e3041f..2791ca0ea5 100644 --- a/test/battle/spread_moves.c +++ b/test/battle/spread_moves.c @@ -36,8 +36,8 @@ DOUBLE_BATTLE_TEST("Spread Moves: No damage will be dealt to a mon in an invulne PARAMETRIZE { attackingMove = MOVE_HYPER_VOICE; invulMove = MOVE_DIVE; } PARAMETRIZE { attackingMove = MOVE_LAVA_PLUME; invulMove = MOVE_DIVE; } GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_LAVA_PLUME].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_LAVA_PLUME) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_ZAPDOS); @@ -172,8 +172,8 @@ DOUBLE_BATTLE_TEST("Spread Moves: A spread move attack will be weakened by stron DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (right) and Lightning Rod (left)") { GIVEN { - ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_DISCHARGE].type == TYPE_ELECTRIC); + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_MIMIKYU); OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); } @@ -191,8 +191,8 @@ DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (right) and DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (left) and Lightning Rod (reft)") { GIVEN { - ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_DISCHARGE].type == TYPE_ELECTRIC); + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_MIMIKYU); OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); HP(1); } @@ -210,8 +210,8 @@ DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (left) and L DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Eiscue and Mimikyu (Based on vanilla games)") { GIVEN { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_EISCUE); OPPONENT(SPECIES_MIMIKYU); @@ -229,7 +229,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Eiscue and Mimikyu (Based on vanil DOUBLE_BATTLE_TEST("Spread Moves: Spread move, Gem Boosted, vs Resist Berries") { GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET) { Speed(40); Item(ITEM_NORMAL_GEM); } PLAYER(SPECIES_WYNAUT) { Speed(30); } OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Item(ITEM_CHILAN_BERRY); } @@ -249,7 +249,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Spread move, Gem Boosted, vs Resist Berries") DOUBLE_BATTLE_TEST("Spread Moves: Explosion, Gem Boosted, vs Resist Berries") { GIVEN { - ASSUME(gMovesInfo[MOVE_EXPLOSION].target == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY); PLAYER(SPECIES_WOBBUFFET) { Speed(40); Item(ITEM_NORMAL_GEM); } PLAYER(SPECIES_MISDREAVUS) { Speed(30); } OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Item(ITEM_CHILAN_BERRY); } @@ -270,8 +270,8 @@ DOUBLE_BATTLE_TEST("Spread Moves: Explosion, Gem Boosted, vs Resist Berries") DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Eiscue and Mimikyu with 1 Eject Button") { GIVEN { - ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].target == MOVE_TARGET_BOTH); - ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveTarget(MOVE_RAZOR_LEAF) == MOVE_TARGET_BOTH); + ASSUME(GetMoveCategory(MOVE_RAZOR_LEAF) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(40); } PLAYER(SPECIES_WYNAUT) { Speed(30); } OPPONENT(SPECIES_MIMIKYU) { Speed(20); Item(ITEM_EJECT_BUTTON); } @@ -290,7 +290,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Eiscue and Mimikyu with 1 Eject DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Wide Guard") { GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET) { Speed(40); } PLAYER(SPECIES_WYNAUT) { Speed(20); } OPPONENT(SPECIES_WOBBUFFET) { Speed(30); } @@ -310,7 +310,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Wide Guard") DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs one protecting mon") { GIVEN { - ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); @@ -327,7 +327,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs one protecting mon") DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both opposing mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_PRECIPICE_BLADES].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_GOLEM); @@ -345,7 +345,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both opposing mons" DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both player mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_PRECIPICE_BLADES].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH); PLAYER(SPECIES_GOLEM); PLAYER(SPECIES_ONIX); OPPONENT(SPECIES_WOBBUFFET); @@ -363,7 +363,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both player mons") DOUBLE_BATTLE_TEST("Spread Moves: Not very effective Message on both opposing mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_PRECIPICE_BLADES].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_CHIKORITA); @@ -381,7 +381,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Not very effective Message on both opposing mo DOUBLE_BATTLE_TEST("Spread Moves: Not very effective message on both player mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_PRECIPICE_BLADES].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH); PLAYER(SPECIES_CHIKORITA); PLAYER(SPECIES_TREECKO); OPPONENT(SPECIES_WOBBUFFET); @@ -399,7 +399,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: Not very effective message on both player mons DOUBLE_BATTLE_TEST("Spread Moves: Doesn't affect message on both opposing mons") { GIVEN { - ASSUME(gMovesInfo[MOVE_PRECIPICE_BLADES].target == MOVE_TARGET_BOTH); + ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PIDGEY); diff --git a/test/battle/terrain/starting_terrain.c b/test/battle/starting_status/terrain.c similarity index 100% rename from test/battle/terrain/starting_terrain.c rename to test/battle/starting_status/terrain.c diff --git a/test/battle/status1/burn.c b/test/battle/status1/burn.c index 63d6506fb6..c37768cedf 100644 --- a/test/battle/status1/burn.c +++ b/test/battle/status1/burn.c @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Burn reduces Attack by 50%", s16 damage) PARAMETRIZE { burned = FALSE; } PARAMETRIZE { burned = TRUE; } GIVEN { - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { if (burned) Status1(STATUS1_BURN); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/status1/freeze.c b/test/battle/status1/freeze.c index f218430909..ed83675457 100644 --- a/test/battle/status1/freeze.c +++ b/test/battle/status1/freeze.c @@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Freeze has a 20% chance of being thawed") SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks") { GIVEN { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks") SINGLE_BATTLE_TEST("Freeze is thawed by user's Flame Wheel") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].thawsUser); + ASSUME(MoveThawsUser(MOVE_FLAME_WHEEL)); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/status1/frostbite.c b/test/battle/status1/frostbite.c index a7776e5e2e..f45508f800 100644 --- a/test/battle/status1/frostbite.c +++ b/test/battle/status1/frostbite.c @@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent") s16 normaleDamage; GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); } } WHEN { diff --git a/test/battle/status2/confusion.c b/test/battle/status2/confusion.c index 4115123b3c..c2ee92dd09 100644 --- a/test/battle/status2/confusion.c +++ b/test/battle/status2/confusion.c @@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power") { s16 damage[2]; - ASSUME(gMovesInfo[MOVE_TACKLE].power == 40); + ASSUME(GetMovePower(MOVE_TACKLE) == 40); PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION); GIVEN { diff --git a/test/battle/weather/rain.c b/test/battle/weather/rain.c index 3359d25a81..0620aae100 100644 --- a/test/battle/weather/rain.c +++ b/test/battle/weather/rain.c @@ -4,8 +4,8 @@ // Please add Rain interactions with move, item and ability effects on their respective files. ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); } SINGLE_BATTLE_TEST("Rain multiplies the power of Fire-type moves by 0.5x", s16 damage) diff --git a/test/battle/weather/sandstorm.c b/test/battle/weather/sandstorm.c index 38502cbbc7..dcac3f71c3 100644 --- a/test/battle/weather/sandstorm.c +++ b/test/battle/weather/sandstorm.c @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Sandstorm multiplies the special defense of Rock-types by 1. PARAMETRIZE { move = MOVE_SANDSTORM; } PARAMETRIZE { move = MOVE_CELEBRATE; } GIVEN { - ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL); + ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL); PLAYER(SPECIES_WOBBUFFET) ; OPPONENT(SPECIES_NOSEPASS); } WHEN { diff --git a/test/battle/weather/snow.c b/test/battle/weather/snow.c index 6c084f6b7a..7b4e4cb2ff 100644 --- a/test/battle/weather/snow.c +++ b/test/battle/weather/snow.c @@ -4,10 +4,10 @@ // Please add Snow interactions with move, item and ability effects on their respective files. ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ICE && gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ICE); ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE || gSpeciesInfo[SPECIES_GLALIE].types[1] == TYPE_ICE); - ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL); } SINGLE_BATTLE_TEST("Snow multiplies the defense of Ice-types by 1.5x", s16 damage) diff --git a/test/battle/weather/sunlight.c b/test/battle/weather/sunlight.c index 6cf6348987..796ad3c3af 100644 --- a/test/battle/weather/sunlight.c +++ b/test/battle/weather/sunlight.c @@ -4,8 +4,8 @@ // Please add Sunlight interactions with move, item and ability effects on their respective files. ASSUMPTIONS { - ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE); - ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER); + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); } SINGLE_BATTLE_TEST("Sunlight multiplies the power of Fire-type moves by 1.5x", s16 damage) diff --git a/test/pokemon.c b/test/pokemon.c index f5431559ee..00b08ebb79 100644 --- a/test/pokemon.c +++ b/test/pokemon.c @@ -210,6 +210,50 @@ TEST("givemon [simple]") EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100); } +TEST("givemon respects perfectIVCount") +{ + ZeroPlayerPartyMons(); + u32 perfectIVs[6] = {0}; + + ASSUME(gSpeciesInfo[SPECIES_MEW].perfectIVCount == 3); + ASSUME(gSpeciesInfo[SPECIES_CELEBI].perfectIVCount == 3); + ASSUME(gSpeciesInfo[SPECIES_JIRACHI].perfectIVCount == 3); + ASSUME(gSpeciesInfo[SPECIES_MANAPHY].perfectIVCount == 3); + ASSUME(gSpeciesInfo[SPECIES_VICTINI].perfectIVCount == 3); + ASSUME(gSpeciesInfo[SPECIES_DIANCIE].perfectIVCount == 3); + + RUN_OVERWORLD_SCRIPT( + givemon SPECIES_MEW, 100; + givemon SPECIES_CELEBI, 100; + givemon SPECIES_JIRACHI, 100; + givemon SPECIES_MANAPHY, 100; + givemon SPECIES_VICTINI, 100; + givemon SPECIES_DIANCIE, 100; + ); + + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MEW); + EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), SPECIES_CELEBI); + EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_SPECIES), SPECIES_JIRACHI); + EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_SPECIES), SPECIES_MANAPHY); + EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_SPECIES), SPECIES_VICTINI); + EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_SPECIES), SPECIES_DIANCIE); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_LEVEL), 100); + EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_LEVEL), 100); + for (u32 j = 0; j < 6; j++) + { + for (u32 k = 0; k < NUM_STATS; k++) + { + if (GetMonData(&gPlayerParty[j], MON_DATA_HP_IV + k) == MAX_PER_STAT_IVS) + perfectIVs[j]++; + } + EXPECT_GE(perfectIVs[j], 3); + } +} + TEST("givemon [moves]") { ZeroPlayerPartyMons(); diff --git a/test/test_runner.c b/test/test_runner.c index d3196a20e1..7a81d1dc9f 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -10,7 +10,7 @@ #include "test_runner.h" #include "test/test.h" -#define TIMEOUT_SECONDS 55 +#define TIMEOUT_SECONDS 60 void CB2_TestRunner(void); @@ -276,7 +276,7 @@ top: { if (gTasks[i].isActive) { - Test_MgbaPrintf("%p: task not freed", gTasks[i].func); + Test_MgbaPrintf(":L%s:%d - %p: task not freed", gTestRunnerState.test->filename, SourceLine(0), gTasks[i].func); gTestRunnerState.result = TEST_RESULT_FAIL; } } diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 50d389c545..eda9c1eda5 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -160,6 +160,7 @@ static void BattleTest_SetUp(void *data) { const struct BattleTest *test = data; memset(STATE, 0, sizeof(*STATE)); + TestInitConfigData(); InvokeTestFunction(test); STATE->parameters = STATE->parametersCount; if (STATE->parametersCount == 0 && test->resultsSize > 0) @@ -1416,6 +1417,7 @@ static void BattleTest_TearDown(void *data) // Free resources that aren't cleaned up when the battle was // aborted unexpectedly. ClearFlagAfterTest(); + TestFreeConfigData(); if (STATE->tearDownBattle) TearDownBattle(); } @@ -1512,6 +1514,12 @@ void SetFlagForTest(u32 sourceLine, u16 flagId) FlagSet(flagId); } +void TestSetConfig(u32 sourceLine, enum GenConfigTag configTag, u32 value) +{ + INVALID_IF(!STATE->runGiven, "WITH_CONFIG outside of GIVEN"); + SetGenConfig(configTag, value); +} + void ClearFlagAfterTest(void) { if (DATA.flagId != 0) @@ -1766,7 +1774,8 @@ void Moves_(u32 sourceLine, u16 moves[MAX_MON_MOVES]) break; INVALID_IF(moves[i] >= MOVES_COUNT, "Illegal move: %d", moves[i]); SetMonData(DATA.currentMon, MON_DATA_MOVE1 + i, &moves[i]); - SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &gMovesInfo[moves[i]].pp); + u32 pp = GetMovePP(moves[i]); + SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &pp); } DATA.explicitMoves[DATA.currentSide] |= 1 << DATA.currentPartyIndex; } @@ -2084,7 +2093,8 @@ void MoveGetIdAndSlot(s32 battlerId, struct MoveContext *ctx, u32 *moveId, u32 * { INVALID_IF(DATA.explicitMoves[battlerId & BIT_SIDE] & (1 << DATA.currentMonIndexes[battlerId]), "Missing explicit %S", GetMoveName(ctx->move)); SetMonData(mon, MON_DATA_MOVE1 + i, &ctx->move); - SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &gMovesInfo[ctx->move].pp); + u32 pp = GetMovePP(ctx->move); + SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &pp); *moveSlot = i; *moveId = ctx->move; break; @@ -2113,7 +2123,7 @@ void MoveGetIdAndSlot(s32 battlerId, struct MoveContext *ctx, u32 *moveId, u32 * // Check invalid item usage. INVALID_IF(ctx->gimmick == GIMMICK_MEGA && holdEffect != HOLD_EFFECT_MEGA_STONE && species != SPECIES_RAYQUAZA, "Cannot Mega Evolve without a Mega Stone"); INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && holdEffect != HOLD_EFFECT_Z_CRYSTAL, "Cannot use a Z-Move without a Z-Crystal"); - INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && ItemId_GetSecondaryId(item) != gMovesInfo[*moveId].type + INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && ItemId_GetSecondaryId(item) != GetMoveType(*moveId) && GetSignatureZMove(*moveId, species, item) == MOVE_NONE && *moveId != MOVE_PHOTON_GEYSER, // exception because test won't recognize Ultra Necrozma pre-Burst "Cannot turn %S into a Z-Move with %S", GetMoveName(ctx->move), ItemId_GetName(item)); @@ -2175,7 +2185,7 @@ void Move(u32 sourceLine, struct BattlePokemon *battler, struct MoveContext ctx) MoveGetIdAndSlot(battlerId, &ctx, &moveId, &moveSlot, sourceLine); target = MoveGetTarget(battlerId, moveId, &ctx, sourceLine); - if (gMovesInfo[moveId].effect == EFFECT_REVIVAL_BLESSING) + if (GetMoveEffect(moveId) == EFFECT_REVIVAL_BLESSING) requirePartyIndex = MoveGetFirstFainted(battlerId) != PARTY_SIZE; // Check party menu moves. diff --git a/test/text.c b/test/text.c index ed343d1039..781aaaed3e 100644 --- a/test/text.c +++ b/test/text.c @@ -23,10 +23,10 @@ TEST("Move names fit on Pokemon Summary Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; } } - //DebugPrintf("Move %d: %S", GetStringWidth(fontId, gMovesInfo[move].name, 0), gMovesInfo[move].name); - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + //DebugPrintf("Move %d: %S", GetStringWidth(fontId, GetMoveName(move), 0), GetMoveName(move)); + EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); } TEST("Move names fit on Battle Screen") @@ -36,9 +36,9 @@ TEST("Move names fit on Battle Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; } } - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); } TEST("Move names fit on Contest Screen") @@ -48,7 +48,7 @@ TEST("Move names fit on Contest Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; } } // All moves explicitly listed here are too big to fit. switch (move) @@ -56,10 +56,10 @@ TEST("Move names fit on Contest Screen") case MOVE_STOMPING_TANTRUM: case MOVE_NATURES_MADNESS: case MOVE_DOUBLE_IRON_BASH: - EXPECT_GT(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + EXPECT_GT(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); break; default: - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); break; } } @@ -71,9 +71,9 @@ TEST("Move names fit on TMs & HMs Bag Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; } } - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); } TEST("Move names fit on Move Relearner Screen") @@ -83,9 +83,9 @@ TEST("Move names fit on Move Relearner Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; } } - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx); + EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx); } TEST("Move descriptions fit on Pokemon Summary Screen") @@ -95,9 +95,9 @@ TEST("Move descriptions fit on Pokemon Summary Screen") u32 move = MOVE_NONE; for (i = 1; i < MOVES_COUNT; i++) { - PARAMETRIZE_LABEL("%S", gMovesInfo[i].description) { move = i; } + PARAMETRIZE_LABEL("%S", GetMoveDescription(i)) { move = i; } } - EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].description, 0), widthPx); + EXPECT_LE(GetStringWidth(fontId, GetMoveDescription(move), 0), widthPx); } TEST("Item names fit on Bag Screen (list)") diff --git a/tools/trainerproc/main.c b/tools/trainerproc/main.c index f1bcf1bfa4..7cddb06930 100644 --- a/tools/trainerproc/main.c +++ b/tools/trainerproc/main.c @@ -1705,7 +1705,6 @@ static void fprint_trainers(const char *output_path, FILE *f, struct Parsed *par if (!is_empty_string(trainer->mugshot)) { fprintf(f, "#line %d\n", trainer->mugshot_line); - fprintf(f, " .mugshotEnabled = TRUE,\n"); fprintf(f, " .mugshotColor = "); fprint_constant(f, "MUGSHOT_COLOR", trainer->mugshot); fprintf(f, ",\n");