diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 109c4a5930ab..bc9b624f1d43 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -23,8 +23,9 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.7.0 (Default) + - 1.7.1 (Default) - upcoming (Edge) + - 1.7.0 - 1.6.2 - 1.6.1 - 1.6.0 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 74e13a0a353a..512a433eff48 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -23,8 +23,9 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.7.0 (Default) + - 1.7.1 (Default) - upcoming (Edge) + - 1.7.0 - 1.6.2 - 1.6.1 - 1.6.0 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index c449e8b648a1..77d9a217de08 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -23,8 +23,9 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.7.0 (Default) + - 1.7.1 (Default) - upcoming (Edge) + - 1.7.0 - 1.6.2 - 1.6.1 - 1.6.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b56aca13604..c18fb7de37e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Pokeemerald-Expansion Changelogs +## [Version 1.7.1](docs/changelogs/1.7.1.md) - Bugfix Release + ## [Version 1.7.0](docs/changelogs/1.7.0.md) - Feature Release -## [Version 1.6.2](docs/changelogs/1.6.2.md) - Bugfix release +## [Version 1.6.2](docs/changelogs/1.6.2.md) - Bugfix Release diff --git a/INSTALL.md b/INSTALL.md index f82649d7e2c3..0498b468ea48 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -89,6 +89,7 @@ Some tips before proceeding: > If the above command does not work, try the above command but replacing `apt` with `apt-get`. + This will install GCC v10 on Ubuntu 22.04. pokeemerald-expansion works with GCC v10, but remote repositories and the RHH Team use GCC v13 for stricter error-checking. If you want to upgrade from v10 to v13, also follow the devkitpro install instructions. ### Choosing where to store pokeemerald (WSL1) WSL has its own file system that's not natively accessible from Windows, but Windows files *are* accessible from WSL. So you're going to want to store pokeemerald within Windows. @@ -408,6 +409,8 @@ If this works, then proceed to [Installation](#installation). Otherwise, ask for > Where *\* is the path of the folder [where you chose to store pokeemerald](#Choosing-where-to-store-pokeemerald-WSL1). Then run the `git clone` command again. +
+ Depreciated; installing agbcc is optional since 1.7.0. 2. Install agbcc into pokeemerald. The commands to run depend on certain conditions. **You should only follow one of the listed instructions**: - If agbcc has **not been built before** in the folder where you chose to store pokeemerald, run the following commands to build and install it into pokeemerald: @@ -445,6 +448,7 @@ If this works, then proceed to [Installation](#installation). Otherwise, ask for ```bash cd .. ``` +
Now you're ready to [build **pokeemerald**](#build-pokeemerald) ## Build pokeemerald diff --git a/Makefile b/Makefile index db883cb60c6a..ea7adb0e6682 100644 --- a/Makefile +++ b/Makefile @@ -473,7 +473,7 @@ endif $(OBJ_DIR)/ld_script.ld: $(LD_SCRIPT) $(LD_SCRIPT_DEPS) cd $(OBJ_DIR) && sed "s#tools/#../../tools/#g" ../../$(LD_SCRIPT) > ld_script.ld -LDFLAGS = -Map ../../$(MAP) +LDFLAGS = -Map ../../$(MAP) --no-warn-rwx-segments $(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS) libagbsyscall @echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ " @cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld --print-memory-usage -o ../../$@ $(OBJS_REL) $(LIB) | cat @@ -495,7 +495,7 @@ $(OBJ_DIR)/ld_script_test.ld: $(LD_SCRIPT_TEST) $(LD_SCRIPT_DEPS) $(TESTELF): $(OBJ_DIR)/ld_script_test.ld $(OBJS) $(TEST_OBJS) libagbsyscall tools check-tools @echo "cd $(OBJ_DIR) && $(LD) -T ld_script_test.ld -o ../../$@ " @cd $(OBJ_DIR) && $(LD) $(TESTLDFLAGS) -T ld_script_test.ld -o ../../$@ $(OBJS_REL) $(TEST_OBJS_REL) $(LIB) - $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent + $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) -d0 --silent $(PATCHELF) $(TESTELF) gTestRunnerArgv "$(TESTS)\0" ifeq ($(GITHUB_REPOSITORY_OWNER),rh-hideout) diff --git a/README.md b/README.md index c48adac1fe29..5117bf22ed64 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ pokeemerald-expansion is a decomp hack base project based off pret's [pokeemeral 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 v1.7.0 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion v1.7.1 https://github.com/rh-hideout/pokeemerald-expansion/ ``` ## What features are included? @@ -166,7 +166,7 @@ With this, you'll get the latest version of pokeemerald-expansion, plus a couple ## **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`. -- Once you have your remote set up, run the command `git pull RHH expansion/1.7.0`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.7.1`. ### 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 :) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index ff3eca273cc6..c7377378b768 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1566,6 +1566,10 @@ callnative BS_TryTriggerStatusForm .endm + .macro setphotongeysercategory + callnative BS_SetPhotonGeyserCategory + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES @@ -2134,10 +2138,6 @@ .4byte \failInstr .endm - .macro photongeysercheck battler:req - various \battler, VARIOUS_PHOTON_GEYSER_CHECK - .endm - .macro shellsidearmcheck various BS_ATTACKER, VARIOUS_SHELL_SIDE_ARM_CHECK .endm diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 389af990e61a..3943be627884 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -5389,11 +5389,11 @@ Move_FOUL_PLAY: createsprite gFoulPlayImpactTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 0x1, 0x1 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1 playsewithpan SE_M_VITAL_THROW SOUND_PAN_TARGET - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0xa, 0x0, 0x0 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0xa, 0x0, 0x0 createsprite gFoulPlayRingTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x100, 0x0 delay 0x8 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0xa, 0x0, 0x0 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0xa, 0x0, 0x0 createsprite gFoulPlayRingTemplate, ANIM_ATTACKER, 3, 0x0, 0x0, 0x100, 0x0 waitforvisualfinish clearmonbg ANIM_TARGET @@ -10409,7 +10409,7 @@ Move_LIGHT_OF_RUIN:: delay 0x10 createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x10, 0x0, 0x7FFF waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x1, 0x0, 0x0, 0x0 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x1, 0x0, 0x0, 0x0 waitforvisualfinish end LightOfRuinBeam: @@ -11147,7 +11147,7 @@ SolarBladeUnleash: loadspritegfx ANIM_TAG_SUNLIGHT @sun rays monbg ANIM_ATTACKER setalpha 13, 3 - createvisualtask AnimTask_BlendBattleAnimPal 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 0, 6, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 0, 6, 0x7fff waitforvisualfinish playsewithpan SE_M_SWORDS_DANCE, SOUND_PAN_ATTACKER createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 16, 6, 1, 4 @@ -11164,7 +11164,7 @@ SolarBladeUnleash: delay 0x2 createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 12, 1 waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 6, 0, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 6, 0, 0x7fff waitforvisualfinish call UnsetPsychicBg clearmonbg ANIM_ATTACKER @@ -15389,7 +15389,7 @@ Move_SILK_TRAP:: Move_SNOWSCAPE:: loadspritegfx ANIM_TAG_SNOWFLAKES playsewithpan SE_M_GUST, SOUND_PAN_ATTACKER - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 0, 4, RGB(11, 18, 22) + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 0, 4, RGB(11, 18, 22) waitforvisualfinish createvisualtask AnimTask_CreateSnowflakes, 2, 0, 3, 120 createvisualtask AnimTask_CreateSnowflakes, 2, 0, 3, 120 @@ -15398,7 +15398,7 @@ Move_SNOWSCAPE:: playsewithpan SE_M_GUST2, SOUND_PAN_ATTACKER delay 30 waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 4, 0, RGB(11, 18, 22) + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 4, 0, RGB(11, 18, 22) waitforvisualfinish end @@ -15560,7 +15560,7 @@ Move_DRAGON_ENERGY:: createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATTACKER, 0, 4, 0, 11, RGB(31, 28, 31) @;Pinkish White waitforvisualfinish playsewithpan SE_M_DETECT, SOUND_PAN_TARGET - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x1, 0x10, 0x0, 0x2C5E @;Regidrago Reddish Reddish, Purple + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x10, 0x0, 0x2C5E @;Regidrago Reddish Reddish, Purple createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, -120, 0, 0, 1 @;Slide off off, screen waitforvisualfinish playsewithpan SE_M_SOLAR_BEAM, SOUND_PAN_TARGET @@ -16098,7 +16098,7 @@ Move_CHLOROBLAST:: createvisualtask AnimTask_AllBattlersVisible, 0xA, clearmonbg ANIM_DEF_PARTNER waitbgfadein - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x0, 0x0 @;From Black + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x0, 0x0 @;From Black end ChloroblastShot: createsprite gSpriteTemplate_ChloroblastShot, ANIM_TARGET, 2, 0, 0, 0x19 @@ -16466,7 +16466,7 @@ Move_CEASELESS_EDGE:: createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, 0x0, 0x5 waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA, - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x1, 0x10, 0x0, 0x7FFF @;From White + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x10, 0x0, 0x7FFF @;From White waitforvisualfinish end @@ -16929,6 +16929,29 @@ ChillyReceptionSnowballs: delay 3 return +Move_BURNING_BULWARK:: + goto Move_PROTECT + +Move_ALLURING_VOICE:: + loadspritegfx ANIM_TAG_THIN_RING + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0x8, 0x6e7d + waitforvisualfinish + createvisualtask SoundTask_PlayCryWithEcho, 5, FALSE + createsprite gHyperVoiceRingSpriteTemplate, ANIM_ATTACKER, 0, 45, 0, 0, 0, 0, 0, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 6, 1 + createvisualtask AnimTask_ShakeBattleTerrain, 2, 1, 0, 6, 1 + createvisualtask SoundTask_WaitForCry, 5 + delay 0xA + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 26, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 26, 1 + waitforvisualfinish + createvisualtask SoundTask_WaitForCry, 0x5 + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x8, 0x0, 0x6e7d + waitforvisualfinish + end + Move_TERA_BLAST:: Move_AXE_KICK:: Move_LAST_RESPECTS:: @@ -16980,13 +17003,11 @@ Move_IVY_CUDGEL:: Move_ELECTRO_SHOT:: Move_TERA_STARSTORM:: Move_FICKLE_BEAM:: -Move_BURNING_BULWARK:: Move_THUNDERCLAP:: Move_MIGHTY_CLEAVE:: Move_TACHYON_CUTTER:: Move_HARD_PRESS:: Move_DRAGON_CHEER:: -Move_ALLURING_VOICE:: Move_TEMPER_FLARE:: Move_SUPERCELL_SLAM:: Move_PSYCHIC_NOISE:: @@ -16998,21 +17019,6 @@ Move_MALIGNANT_CHAIN:: Move_NONE: Move_MIRROR_MOVE: Move_POUND: -Move_833: -Move_834: -Move_835: -Move_836: -Move_837: -Move_838: -Move_839: -Move_840: -Move_841: -Move_842: -Move_843: -Move_844: -Move_845: -Move_846: -Move_847: loadspritegfx ANIM_TAG_IMPACT monbg ANIM_TARGET setalpha 12, 8 @@ -19368,7 +19374,7 @@ Move_TELEPORT: call UnsetPsychicBg waitforvisualfinish end - + DoubleTeamAnimRet: setalpha 12, 8 monbg ANIM_ATK_PARTNER @@ -21863,14 +21869,14 @@ Move_DRAGON_RAGE: Move_RAIN_DANCE: loadspritegfx ANIM_TAG_RAIN_DROPS playsewithpan SE_M_RAIN_DANCE, SOUND_PAN_ATTACKER - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 0, 4, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 0, 4, RGB_BLACK waitforvisualfinish createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 120 createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 120 delay 120 delay 30 waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 4, 0, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 4, 0, RGB_BLACK waitforvisualfinish end @@ -23303,7 +23309,7 @@ Move_SUNNY_DAY: loadspritegfx ANIM_TAG_SUNLIGHT monbg ANIM_ATK_PARTNER setalpha 13, 3 - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 0, 6, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 0, 6, RGB_WHITE waitforvisualfinish panse_adjustnone SE_M_PETAL_DANCE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0 call SunnyDayLightRay @@ -23311,7 +23317,7 @@ Move_SUNNY_DAY: call SunnyDayLightRay call SunnyDayLightRay waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 6, 0, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 6, 0, RGB_WHITE waitforvisualfinish clearmonbg ANIM_ATK_PARTNER blendoff @@ -23527,9 +23533,9 @@ Move_HAZE: playsewithpan SE_M_HAZE, 0 createvisualtask AnimTask_HazeScrollingFog, 5 delay 30 - createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS, 2, 0, 16, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS_2, 2, 0, 16, RGB_BLACK delay 90 - createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS, 1, 16, 0, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_BATTLERS_2, 1, 16, 0, RGB_BLACK end Move_FIRE_PUNCH: @@ -24874,7 +24880,7 @@ Move_MORNING_SUN: loadspritegfx ANIM_TAG_BLUE_STAR createvisualtask AnimTask_MorningSunLightBeam, 5 delay 8 - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 8, 0, 12, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 8, 0, 12, RGB_WHITE delay 14 call MorningSunStar call MorningSunStar @@ -24891,7 +24897,7 @@ Move_MORNING_SUN: call MorningSunStar call MorningSunStar call MorningSunStar - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 3, 12, 0, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 3, 12, 0, RGB_WHITE waitforvisualfinish waitsound call HealingEffect @@ -27196,13 +27202,13 @@ General_Rain: RainDrops: loadspritegfx ANIM_TAG_RAIN_DROPS playsewithpan SE_M_RAIN_DANCE, SOUND_PAN_ATTACKER - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 0, 4, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 0, 4, RGB_BLACK waitforvisualfinish createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 60 createvisualtask AnimTask_CreateRaindrops, 2, 0, 3, 60 delay 50 waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 4, 0, RGB_BLACK + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 2, 4, 0, RGB_BLACK waitforvisualfinish return @@ -27651,14 +27657,14 @@ General_Rainbow:: call RainDrops delay 30 loadspritegfx ANIM_TAG_SUNLIGHT - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 0, 6, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 0, 6, RGB_WHITE waitforvisualfinish panse_adjustnone SE_M_PETAL_DANCE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0 call SunnyDayLightRay call SunnyDayLightRay call SunnyDayLightRay waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 6, 0, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS_2), 1, 6, 0, RGB_WHITE waitforvisualfinish delay 30 fadetobg BG_RAINBOW @@ -28831,7 +28837,7 @@ FinishCorkscrewCrash: call CorkscrewCrashSprayRocks delay 0x6 call CorkscrewCrashSprayRocks - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x10, 0x7fff waitforvisualfinish delay 0x10 call ResetFromWhiteScreen @@ -28914,7 +28920,7 @@ FinishInfernoOverdrive: call InfernoOverdriveExplosion delay 0x6 call InfernoOverdriveExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x1, 0x0, 0x10, 0x001b @ red bg pal + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x0, 0x10, 0x001b @ red bg pal delay 0x6 call InfernoOverdriveExplosion waitforvisualfinish @@ -29273,7 +29279,7 @@ BloomDoomPetalBlast: ResetFromGreenScreen: createvisualtask AnimTask_AllBattlersInvisible, 0xA waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x2, 0x0, 0x0, 0x33ED @Everything from green + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x2, 0x0, 0x0, 0x33ED @Everything from green restorebg waitbgfadeout setarg 0x7 0xffff @@ -29897,7 +29903,7 @@ DevastatingDrakeUniversalEnding: waitforvisualfinish createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_TARGET, 0x2, 0x10, 0x0, 0x40c0 @ fade from purple waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x2, 0x0, 0x0, 0x0 @ reset all colours + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x2, 0x0, 0x0, 0x0 @ reset all colours waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA waitforvisualfinish @@ -30090,7 +30096,7 @@ Move_BLACK_HOLE_ECLIPSE:: unloadspritegfx ANIM_TAG_BLACK_BALL_2 loadspritegfx ANIM_TAG_EXPLOSION_2 call BlackHoleEclipseExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x1, 0x0, 0x10, 0x7fff @ bg to white pal + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x0, 0x10, 0x7fff @ bg to white pal call BlackHoleEclipseExplosion waitforvisualfinish delay 0x18 @@ -30121,7 +30127,7 @@ BlackHoleEclipseExplosion: ResetFromWhiteScreen: createvisualtask AnimTask_AllBattlersInvisible, 0xA waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x2, 0x0, 0x0, 0x7FFF @everything from white + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x2, 0x0, 0x0, 0x7FFF @everything from white restorebg waitbgfadeout setarg 0x7 0xffff @@ -30440,10 +30446,10 @@ CatastropikaFinish: call CatastropikaThundering call CatastropikaThundering call CatastropikaThundering - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x0, 0x10, 0x7fff @ bg to white + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x0, 0x10, 0x7fff @ bg to white call CatastropikaThundering waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x10, 0x0, 0x7fff @ bg to white + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x10, 0x0, 0x7fff @ bg to white createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0x0, 0x10 @fix tgt position waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA @@ -30647,11 +30653,11 @@ Move_10000000_VOLT_THUNDERBOLT:: @ createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0x0, 0x0, 0x37, 0x2c, 0x40, 0x28, 0x1, 0x8003 @ createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0x0, 0x0, 0x37, 0x2c, 0x80, 0x28, 0x0, 0x8003 @ createsprite gSparkElectricityFlashingSpriteTemplate, ANIM_TARGET, 4, 0x0, 0x00, 0x37, 0x2c, SOUND_PAN_ATTACKER, 0x28, 0x2, 0x8003 - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x10, 0x7fff call TenMillionVoltThunderboltSparkGeyser waitforvisualfinish delay 0x10 - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0x10, 0x0, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0x10, 0x0, 0x7fff waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA waitforvisualfinish @@ -30867,10 +30873,10 @@ StokedSparksurferSparkGeyser: Move_EXTREME_EVOBOOST:: loadspritegfx ANIM_TAG_LEER @leer - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0x0, 0x10, 0x0000 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0x0, 0x10, 0x0000 waitforvisualfinish createvisualtask AnimTask_AllBattlersInvisible, 0xA - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 3, 0, 0, 0 @Remove fading on everyone + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 3, 0, 0, 0 @Remove fading on everyone waitforvisualfinish playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER createsprite gLeerSpriteTemplate, ANIM_ATTACKER, 2, 0x18, 0xfff4 @@ -31079,7 +31085,7 @@ PulverizingPancakeFinish: delay 0x5 loadspritegfx ANIM_TAG_EXPLOSION @explosion call PulverizingPancakeExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x10, 0x7fff @ everything goes white + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x10, 0x7fff @ everything goes white call PulverizingPancakeExplosion waitforvisualfinish call ResetFromWhiteScreen @@ -31172,7 +31178,7 @@ GenesisSupernovaFinish: unloadspritegfx ANIM_TAG_METEOR @superpower call GenesisSupernovaBubbleExplosion call GenesisSupernovaBubbleExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0x0, 0x10, 0x7fff call GenesisSupernovaBubbleExplosion waitforvisualfinish delay 0x10 @@ -31655,7 +31661,7 @@ Move_MALICIOUS_MOONSAULT:: call MaliciousMoonsaultExplosion delay 0x6 call MaliciousMoonsaultExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x1, 0x0, 0x10, 0x001b @ fade all to red + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x1, 0x0, 0x10, 0x001b @ fade all to red delay 0x6 call MaliciousMoonsaultExplosion createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0x0, 0x10 @@ -31978,10 +31984,10 @@ SplinteredStormshardsByPlayer: call SplinteredStormshardsExplosionOpponent call SplinteredStormshardsExplosionOpponent SplinteredStormshardsEnd: - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x0, 0x10, 0x7fff call SplinteredStormshardsBrownExplode waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x10, 0x0, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x10, 0x0, 0x7fff waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA waitforvisualfinish @@ -32227,7 +32233,7 @@ Move_LETS_SNUGGLE_FOREVER:: delay 0x8 call LetsSnuggleForeverTears waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x10, 0x0000 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x10, 0x0000 waitforvisualfinish loadspritegfx ANIM_TAG_SPARKLE_4 @detect playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER @@ -32429,7 +32435,7 @@ ClangorousSoulblazeOnPlayer: createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0x60, 0xffe0, ANIM_ATTACKER, 0x1 call ClangorousSoulblazePulse_2 delay 0x5 - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x0, 0x10, 0x7fff playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER createsprite gExplosionSpriteTemplate, ANIM_ATTACKER, 3, 0x65, 0xfff0, ANIM_ATTACKER, 0x1 call ClangorousSoulblazePulse_3 @@ -32500,7 +32506,7 @@ ClangorousSoulblazeOnOpponent: createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, 0x60, 0x45, ANIM_ATTACKER, 0x1 call ClangorousSoulblazePulse_2 delay 0x5 - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x0, 0x10, 0x7fff playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER createsprite gExplosionSpriteTemplate, ANIM_TARGET, 3, 0x65, 0x35, ANIM_ATTACKER, 0x1 call ClangorousSoulblazePulse_3 @@ -32654,7 +32660,7 @@ Move_GUARDIAN_OF_ALOLA:: call GuardianOfAlolaRockGeyser call GuardianOfAlolaRockGeyser call GuardianOfAlolaRocksTarget - createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS), 0x3, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS_2), 0x3, 0x0, 0x10, 0x7fff call GuardianOfAlolaRockGeyser call GuardianOfAlolaRockGeyser call GuardianOfAlolaRockGeyser @@ -32825,7 +32831,7 @@ SearingSunrazeSmashImpact: call SearingSunrazeSmashInferno call SearingSunrazeSmashInferno call SearingSunrazeSmashInferno - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x4, 0x0, 0x10, 0x001b @full red + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x4, 0x0, 0x10, 0x001b @full red call SearingSunrazeSmashInferno call SearingSunrazeSmashInferno call SearingSunrazeSmashInferno @@ -32905,7 +32911,7 @@ SearingSunrazeSmashCharge: ResetFromRedScreen: createvisualtask AnimTask_AllBattlersInvisible, 0xA waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x2, 0x0, 0x0, 0x1B @Everything from red + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x2, 0x0, 0x0, 0x1B @Everything from red restorebg waitbgfadeout setarg 0x7 0xffff @@ -33035,7 +33041,7 @@ MenacingMoonrazeMaelstromFinish: createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 76, 1 call MenacingMoonrazeMaelstromExplosion call MenacingMoonrazeMaelstromExplosion - createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x0, 0x10, 0x7fff + createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x0, 0x10, 0x7fff call MenacingMoonrazeMaelstromExplosion waitforvisualfinish call ResetFromWhiteScreen @@ -33182,7 +33188,7 @@ Move_LIGHT_THAT_BURNS_THE_SKY:: clearmonbg ANIM_TARGET waitforvisualfinish delay 0x10 - createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS), 0x0, 0x10, 0x0, 0x43FF + createvisualtask AnimTask_BlendBattleAnimPal, 0x2, (F_PAL_BG | F_PAL_BATTLERS_2), 0x0, 0x10, 0x0, 0x43FF restorebg waitbgfadeout end @@ -33384,9 +33390,9 @@ Move_SOUL_STEALING_7_STAR_STRIKE:: waitforvisualfinish blendoff restorebg - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS), 0x2, 0x10, 0x0, 0x0 @everything from black + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, (F_PAL_BG | F_PAL_BATTLERS_2), 0x2, 0x10, 0x0, 0x0 @everything from black waitforvisualfinish - createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS, 0x2, 0x0, 0x0, 0x0 + createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BATTLERS_2, 0x2, 0x0, 0x0, 0x0 waitforvisualfinish createvisualtask AnimTask_AllBattlersVisible, 0xA waitforvisualfinish diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c70c76740a2c..cddbdcc04403 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -441,6 +441,8 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectHit @ EFFECT_RAGE_FIST .4byte BattleScript_EffectDoodle @ EFFECT_DOODLE .4byte BattleScript_EffectFilletAway @ EFFECT_FILLET_AWAY + .4byte BattleScript_EffectHit @ EFFECT_IVY_CUDGEL + .4byte BattleScript_EffectHit @ EFFECT_FICKLE_BEAM BattleScript_EffectFilletAway: attackcanceler @@ -1061,12 +1063,25 @@ BattleScript_EffectMeteorBeam:: @ DecideTurn jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn - setbyte sTWOTURN_STRINGID, B_MSG_TURN1_METEOR_BEAM + jumpifmove MOVE_METEOR_BEAM, BattleScript_SetStringMeteorBeam + jumpifmove MOVE_ELECTRO_SHOT, BattleScript_SetStringElectroShock +BattleScript_TryCharging: call BattleScript_FirstChargingTurnMeteorBeam + jumpifmove MOVE_METEOR_BEAM, BattleScript_TryMeteorBeam + jumpifweatheraffected BS_ATTACKER, B_WEATHER_RAIN, BattleScript_TwoTurnMovesSecondTurn @ Check for move Electro Shot +BattleScript_TryMeteorBeam: jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_MoveEnd call BattleScript_PowerHerbActivation goto BattleScript_TwoTurnMovesSecondTurn +BattleScript_SetStringMeteorBeam: + setbyte sTWOTURN_STRINGID, B_MSG_TURN1_METEOR_BEAM + goto BattleScript_TryCharging + +BattleScript_SetStringElectroShock: + setbyte sTWOTURN_STRINGID, B_MSG_TURN1_ELECTRO_SHOCK + goto BattleScript_TryCharging + BattleScript_FirstChargingTurnMeteorBeam:: attackcanceler flushtextbox @@ -1242,28 +1257,8 @@ BattleScript_EffectShellSideArm: goto BattleScript_EffectHit BattleScript_EffectPhotonGeyser: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - ppreduce - critcalc - damagecalc - adjustdamage - photongeysercheck BS_ATTACKER - attackanimation - waitanimation - effectivenesssound - hitanimation BS_TARGET - waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET - critmessage - waitmessage B_WAIT_TIME_LONG - resultmessage - waitmessage B_WAIT_TIME_LONG - seteffectwithchance - tryfaintmon BS_TARGET - goto BattleScript_MoveEnd + setphotongeysercategory + goto BattleScript_EffectHit BattleScript_EffectAuraWheel: @ Aura Wheel can only be used by Morpeko jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_FULL_BELLY, BattleScript_EffectSpeedUpHit @@ -1696,15 +1691,28 @@ BattleScript_StrengthSapTryHp: attackanimation waitanimation BattleScript_StrengthSapHp: + jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapManipulateDmg jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_MoveEnd jumpiffullhp BS_ATTACKER, BattleScript_MoveEnd +BattleScript_StrengthSapManipulateDmg: manipulatedamage DMG_BIG_ROOT orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapLiquidOoze healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER printstring STRINGID_PKMNENERGYDRAINED waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd +BattleScript_StrengthSapLiquidOoze: + call BattleScript_AbilityPopUpTarget + manipulatedamage DMG_CHANGE_SIGN + setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB_OOZE + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + printfromtable gAbsorbDrainStringIds + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_ATTACKER + goto BattleScript_MoveEnd BattleScript_StrengthSapMustLower: statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_MoveEnd jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY, BattleScript_MoveEnd @@ -8103,6 +8111,7 @@ BattleScript_IllusionOff:: return BattleScript_CottonDownActivates:: + copybyte sSAVED_BATTLER, gBattlerAttacker showabilitypopup BS_TARGET pause B_WAIT_TIME_LONG destroyabilitypopup @@ -8127,6 +8136,7 @@ BattleScript_CottonDownLoopIncrement: jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_CottonDownLoop BattleScript_CottonDownReturn: swapattackerwithtarget + copybyte gBattlerAttacker, sSAVED_BATTLER return BattleScript_AnticipationActivates:: diff --git a/docs/changelogs/1.7.1.md b/docs/changelogs/1.7.1.md new file mode 100644 index 000000000000..c30c77512ff2 --- /dev/null +++ b/docs/changelogs/1.7.1.md @@ -0,0 +1,63 @@ +# Version 1.7.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.7.1`. +``` + +## 🧬 General 🧬 +### Changed +* Deprecate agbcc and clarify gcc version usage in install instructions. by @GraionDilach in https://github.com/rh-hideout/pokeemerald-expansion/pull/3788 +### Fixed +* Fix Update Message Saying 1.6.2 by @kaicardenas2 in https://github.com/rh-hideout/pokeemerald-expansion/pull/3759 +* Fix exp gain when defeating two opponents at once by @ghoulslash in https://github.com/rh-hideout/pokeemerald-expansion/pull/3798 +* Fix debug menu toggling first flag by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3796 + +## 🐉 Pokémon 🐉 +### Fixed +* Fix Maushold-3 and Maushold-4 icons being swapped by @kittenchilly in https://github.com/rh-hideout/pokeemerald-expansion/pull/3809 +* Fixes Minior form change and likely other forms by @AlexOn1ine in https://github.com/rh-hideout/pokeemerald-expansion/pull/3822 +* Fix P_FAMILY #if blocks for Regigigas and Giratina in front_pic_anims.h by @gabrielcowley in https://github.com/rh-hideout/pokeemerald-expansion/pull/3823 + +## 🤹 Moves 🤹 +### Added +* Adds data for The Indigo Disk moves by @Bassoonian in https://github.com/rh-hideout/pokeemerald-expansion/pull/3852 + * Many moves still have placeholder effects. +### Fixed +* Fix Telekinesis not working by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3763 +* Fix Ion Deluge interaction with Volt Absorb andLightning Rod by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3764 +* Fix Max Moves animations by @GraionDilach in https://github.com/rh-hideout/pokeemerald-expansion/pull/3769 +* Fix Cotton Down overwriting gBattlerAttacker by @ghoulslash in https://github.com/rh-hideout/pokeemerald-expansion/pull/3783 +* Fix Photon Geyser by @AlexOn1ine in https://github.com/rh-hideout/pokeemerald-expansion/pull/3803 and https://github.com/rh-hideout/pokeemerald-expansion/pull/3807 +* Fix Metronome crash by @Bassoonian in https://github.com/rh-hideout/pokeemerald-expansion/pull/3852 + +## 🎭 Abilities 🎭 +### Fixed +* Fix Ice Face ignoring move effects by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3755 +* Fix Frisk ability pop-up showing wrong battler by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3762 +* Prankster tests + fixes by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3766 + +## 🧶 Items 🧶 +### Fixed +* Fixes Item Metronome damage by @AlexOn1ine in https://github.com/rh-hideout/pokeemerald-expansion/pull/3767 +* Fix gem boost description + test by @Bassoonian in https://github.com/rh-hideout/pokeemerald-expansion/pull/3817 + +## 🧹 Cleanup 🧹 +* Clear BattleScripting struct at the battle start by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3776 +* Fix Rain Dance and Sunny Day not blending opponent sprite by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3785 +* Same lists for healing moves by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3787 +* [battle_controller_player.c] refactor and fix buffer overread by @SBird1337 in https://github.com/rh-hideout/pokeemerald-expansion/pull/3792 +* Make overworld weather-based terrain setting effects use B_MSG_TERRAIN_SET constants for intro text by @ravepossum in https://github.com/rh-hideout/pokeemerald-expansion/pull/3793 +* Clear Sky Battle & Dynamax flags upon whiteout by @Bassoonian in https://github.com/rh-hideout/pokeemerald-expansion/pull/3830 + +## 🧪 Test Runner 🧪 +### Added +* Small test runner improvements by @mrgriffin in https://github.com/rh-hideout/pokeemerald-expansion/pull/3761 +* EXPECT_MUL_EQ thresholds are always at least ±1 by @kittenchilly in https://github.com/rh-hideout/pokeemerald-expansion/pull/3768 +* Added last CannotUseItemsInBattle tests by @LOuroboros in https://github.com/rh-hideout/pokeemerald-expansion/pull/3789 + +## New Contributors +* @kaicardenas2 made their first contribution in https://github.com/rh-hideout/pokeemerald-expansion/pull/3759 + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.7.0...expansion/1.7.1 diff --git a/graphics/pokemon/maushold/four/icon.png b/graphics/pokemon/maushold/four/icon.png index 728aca58a1c5..97c2d708268e 100755 Binary files a/graphics/pokemon/maushold/four/icon.png and b/graphics/pokemon/maushold/four/icon.png differ diff --git a/graphics/pokemon/maushold/icon.png b/graphics/pokemon/maushold/icon.png index 97c2d708268e..728aca58a1c5 100755 Binary files a/graphics/pokemon/maushold/icon.png and b/graphics/pokemon/maushold/icon.png differ diff --git a/include/battle.h b/include/battle.h index ecf8250774ee..fba81a802ac0 100644 --- a/include/battle.h +++ b/include/battle.h @@ -162,6 +162,7 @@ struct ProtectStruct u16 shellTrap:1; u16 maxGuarded:1; u16 silkTrapped:1; + u16 burningBulwarked:1; u16 eatMirrorHerb:1; u16 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy u16 usedAllySwitch:1; @@ -680,7 +681,7 @@ struct BattleStruct u16 arenaStartHp[2]; u8 arenaLostPlayerMons; // Bits for party member, lost as in referee's decision, not by fainting. u8 arenaLostOpponentMons; - u8 alreadyStatusedMoveAttempt; // As bits for battlers; For example when using Thunder Wave on an already paralyzed pokemon. + u8 alreadyStatusedMoveAttempt; // As bits for battlers; For example when using Thunder Wave on an already paralyzed Pokémon. u8 debugBattler; u8 magnitudeBasePower; u8 presentBasePower; @@ -813,6 +814,7 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER || gProtectStructs[battlerId].spikyShielded \ || gProtectStructs[battlerId].kingsShielded \ || gProtectStructs[battlerId].banefulBunkered \ + || gProtectStructs[battlerId].burningBulwarked \ || gProtectStructs[battlerId].obstructed \ || gProtectStructs[battlerId].silkTrapped) @@ -953,7 +955,7 @@ struct BattleSpriteData struct MonSpritesGfx { - void *firstDecompressed; // ptr to the decompressed sprite of the first pokemon + void *firstDecompressed; // ptr to the decompressed sprite of the first Pokémon union { void *ptr[MAX_BATTLERS_COUNT]; u8 *byte[MAX_BATTLERS_COUNT]; diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index f8a5a01cc12f..7207f3b652ae 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -59,7 +59,6 @@ bool32 ShouldRestoreHpBerry(u32 battlerAtk, u32 item); bool32 IsStatBoostingBerry(u32 item); bool32 CanKnockOffItem(u32 battler, u32 item); bool32 IsAbilityOfRating(u32 ability, s8 rating); -s8 GetAbilityRating(u32 ability); bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability); bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move); u32 AI_GetBattlerMoveTargetType(u32 battlerId, u32 move); @@ -118,7 +117,7 @@ bool32 ShouldSetSnow(u32 battler, u32 ability, u32 holdEffect); bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect); bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect); bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef); -bool32 IsHealingMoveEffect(u32 effect); +bool32 IsHealingMove(u32 move); bool32 HasHealingEffect(u32 battler); bool32 IsTrappingMoveEffect(u32 effect); bool32 HasTrappingMoveEffect(u32 battler); diff --git a/include/battle_util.h b/include/battle_util.h index 18b27eed2cb6..575d18edf8f3 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -222,16 +222,6 @@ void RecalcBattlerStats(u32 battler, struct Pokemon *mon); bool32 IsAlly(u32 battlerAtk, u32 battlerDef); bool32 IsGen6ExpShareEnabled(void); -// Ability checks -bool32 IsSkillSwapBannedAbility(u16 ability); -bool32 IsRolePlayDoodleBannedAbility(u16 ability); -bool32 IsRolePlayDoodleBannedAbilityAttacker(u16 ability); -bool32 IsWorrySeedBannedAbility(u16 ability); -bool32 IsGastroAcidBannedAbility(u16 ability); -bool32 IsEntrainmentBannedAbility(u16 ability); -bool32 IsEntrainmentBannedAbilityAttacker(u16 ability); -bool32 IsSimpleBeamBannedAbility(u16 ability); - bool32 CanSleep(u32 battler); bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget); bool32 CanBeBurned(u32 battler); diff --git a/include/config/battle.h b/include/config/battle.h index 5f2b8e29ff79..e963dc775bd1 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -71,6 +71,9 @@ #define B_PP_REDUCED_BY_SPITE GEN_LATEST // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5. #define B_EXTRAPOLATED_MOVE_FLAGS TRUE // Adds move flags to moves that they don't officially have but would likely have if they were in the latest core series game. +// Ability data settings +#define B_UPDATED_ABILITY_DATA GEN_LATEST // Affects flags + // Move accuracy settings #define B_TOXIC_NEVER_MISS GEN_LATEST // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss. #define B_MINIMIZE_DMG_ACC GEN_LATEST // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks. @@ -109,8 +112,8 @@ #define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost. #define B_TRANSFORM_SHINY GEN_LATEST // In Gen4+, Transform will copy the shiny state of the opponent instead of maintaining its own shiny state. #define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms. -#define B_WIDE_GUARD GEN_LATEST // In Gen5 only, Quick Guard has a chance to fail if used consecutively. -#define B_QUICK_GUARD GEN_LATEST // In Gen5 only, Wide Guard has a chance to fail if used consecutively. +#define B_WIDE_GUARD GEN_LATEST // In Gen5 only, Wide Guard has a chance to fail if used consecutively. +#define B_QUICK_GUARD GEN_LATEST // In Gen5 only, Quick Guard has a chance to fail if used consecutively. #define B_IMPRISON GEN_LATEST // In Gen5+, Imprison doesn't fail if opposing pokemon don't have any moves the user knows. #define B_ALLY_SWITCH_FAIL_CHANCE GEN_LATEST // In Gen9, using Ally Switch consecutively decreases the chance of success for each consecutive use. #define B_SKETCH_BANS GEN_LATEST // In Gen9+, Sketch is unable to copy more moves than in previous generations. diff --git a/include/config/item.h b/include/config/item.h index 4ab75611cb94..78324affeaeb 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -10,7 +10,7 @@ #define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8+, the Vitamins no longer have a cap of 100 EV per stat. #define I_BERRY_EV_JUMP GEN_LATEST // In Gen4 only, EV-lowering Berries lower a stat's EV to 100 if it is above 100. #define I_GRISEOUS_ORB_FORM_CHANGE GEN_LATEST // In Gen9+, the Griseous Orb no longer changes Giratina's form when held. -#define I_GEM_BOOST_POWER GEN_LATEST // In Gen5+, the Gem boost power was reduced from 50% to 30%. +#define I_GEM_BOOST_POWER GEN_LATEST // In Gen6+, the Gem boost power was reduced from 50% to 30%. #define I_USE_EVO_HELD_ITEMS_FROM_BAG FALSE // If TRUE, items such as Razor Claw or Electirizer will be usable from the bag to evolve a Pokémon just like in LA. #define I_TYPE_BOOST_POWER GEN_LATEST // In Gen4+, all regular type boosting held items had their power increased from 10% to 20%. eg. Charcoal #define I_SELL_VALUE_FRACTION GEN_LATEST // In Gen9+, items sell for 1/4 of their value instead of 1/2. diff --git a/include/config/species_enabled.h b/include/config/species_enabled.h index 8004abc3bba6..9720f78f0e97 100644 --- a/include/config/species_enabled.h +++ b/include/config/species_enabled.h @@ -594,5 +594,11 @@ #define P_FAMILY_MUNKIDORI P_GEN_9_POKEMON #define P_FAMILY_FEZANDIPITI P_GEN_9_POKEMON #define P_FAMILY_OGERPON P_GEN_9_POKEMON +#define P_FAMILY_GOUGING_FIRE P_GEN_9_POKEMON +#define P_FAMILY_RAGING_BOLT P_GEN_9_POKEMON +#define P_FAMILY_IRON_BOULDER P_GEN_9_POKEMON +#define P_FAMILY_IRON_CROWN P_GEN_9_POKEMON +#define P_FAMILY_TERAPAGOS P_GEN_9_POKEMON +#define P_FAMILY_PECHARUNT P_GEN_9_POKEMON #endif // GUARD_CONFIG_SPECIES_ENABLED_H diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 76e68b245733..ddd7b37843e8 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -642,5 +642,8 @@ #define F_PAL_ADJACENT (F_PAL_DEF_SIDE | F_PAL_ATK_PARTNER) #define F_PAL_ALL_BUT_DEF (F_PAL_ATK_SIDE | F_PAL_DEF_PARTNER) #define F_PAL_ALL_BUT_ATK_PARTNER (F_PAL_ATTACKER | F_PAL_DEF_SIDE) +// The below are only used by AnimTask_BlendBattleAnimPal to get battler sprite palettes by position rather than by role. +// It's redundant with F_PAL_BATTLERS, because they're only ever used together to refer to all the battlers at once. +#define F_PAL_BATTLERS_2 (1 << 7 | 1 << 8 | 1 << 9 | 1 << 10) #endif // GUARD_CONSTANTS_BATTLE_ANIM_H diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index dbaa21f14d25..b1662469e755 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -418,7 +418,9 @@ #define EFFECT_RAGE_FIST 412 #define EFFECT_DOODLE 413 #define EFFECT_FILLET_AWAY 414 +#define EFFECT_IVY_CUDGEL 415 +#define EFFECT_FICKLE_BEAM 416 -#define NUM_BATTLE_MOVE_EFFECTS 415 +#define NUM_BATTLE_MOVE_EFFECTS 417 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_palace.h b/include/constants/battle_palace.h index 85165508922e..1d8c2f2ddad5 100644 --- a/include/constants/battle_palace.h +++ b/include/constants/battle_palace.h @@ -16,12 +16,12 @@ #define PALACE_DATA_WIN_STREAK 1 #define PALACE_DATA_WIN_STREAK_ACTIVE 2 -// Pokemon in Battle Palace have a move "group" type preference depending on nature +// Pokémon in Battle Palace have a move "group" type preference depending on nature #define PALACE_MOVE_GROUP_ATTACK 0 #define PALACE_MOVE_GROUP_DEFENSE 1 #define PALACE_MOVE_GROUP_SUPPORT 2 -// In palace doubles battles pokemon have a target preference depending on nature +// In palace doubles battles Pokémon have a target preference depending on nature #define PALACE_TARGET_STRONGER 0 #define PALACE_TARGET_WEAKER 1 #define PALACE_TARGET_RANDOM 2 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 4899d3703693..95632f09c7dd 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -210,37 +210,36 @@ #define VARIOUS_JUMP_IF_WEATHER_AFFECTED 118 #define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 119 #define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 120 -#define VARIOUS_PHOTON_GEYSER_CHECK 121 -#define VARIOUS_SHELL_SIDE_ARM_CHECK 122 -#define VARIOUS_TRY_NO_RETREAT 123 -#define VARIOUS_TRY_TAR_SHOT 124 -#define VARIOUS_CAN_TAR_SHOT_WORK 125 -#define VARIOUS_CHECK_POLTERGEIST 126 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 127 -#define VARIOUS_TRY_END_NEUTRALIZING_GAS 128 -#define VARIOUS_JUMP_IF_UNDER_200 129 -#define VARIOUS_SET_SKY_DROP 130 -#define VARIOUS_CLEAR_SKY_DROP 131 -#define VARIOUS_SKY_DROP_YAWN 132 -#define VARIOUS_JUMP_IF_HOLD_EFFECT 133 -#define VARIOUS_CURE_CERTAIN_STATUSES 134 -#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 135 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 136 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 137 -#define VARIOUS_SAVE_BATTLER_ITEM 138 -#define VARIOUS_RESTORE_BATTLER_ITEM 139 -#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 140 -#define VARIOUS_SET_BEAK_BLAST 141 -#define VARIOUS_SWAP_SIDE_STATUSES 142 -#define VARIOUS_SWAP_STATS 143 -#define VARIOUS_TEATIME_INVUL 144 -#define VARIOUS_TEATIME_TARGETS 145 -#define VARIOUS_TRY_WIND_RIDER_POWER 146 -#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 147 -#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 148 -#define VARIOUS_STORE_HEALING_WISH 149 -#define VARIOUS_HIT_SWITCH_TARGET_FAILED 150 -#define VARIOUS_TRY_REVIVAL_BLESSING 151 +#define VARIOUS_SHELL_SIDE_ARM_CHECK 121 +#define VARIOUS_TRY_NO_RETREAT 122 +#define VARIOUS_TRY_TAR_SHOT 123 +#define VARIOUS_CAN_TAR_SHOT_WORK 124 +#define VARIOUS_CHECK_POLTERGEIST 125 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 126 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 127 +#define VARIOUS_JUMP_IF_UNDER_200 128 +#define VARIOUS_SET_SKY_DROP 129 +#define VARIOUS_CLEAR_SKY_DROP 130 +#define VARIOUS_SKY_DROP_YAWN 131 +#define VARIOUS_JUMP_IF_HOLD_EFFECT 132 +#define VARIOUS_CURE_CERTAIN_STATUSES 133 +#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 134 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 135 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 136 +#define VARIOUS_SAVE_BATTLER_ITEM 137 +#define VARIOUS_RESTORE_BATTLER_ITEM 138 +#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 139 +#define VARIOUS_SET_BEAK_BLAST 140 +#define VARIOUS_SWAP_SIDE_STATUSES 141 +#define VARIOUS_SWAP_STATS 142 +#define VARIOUS_TEATIME_INVUL 143 +#define VARIOUS_TEATIME_TARGETS 144 +#define VARIOUS_TRY_WIND_RIDER_POWER 145 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 146 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 147 +#define VARIOUS_STORE_HEALING_WISH 148 +#define VARIOUS_HIT_SWITCH_TARGET_FAILED 149 +#define VARIOUS_TRY_REVIVAL_BLESSING 150 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 5b571c9fb259..c4ca5dee437d 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -697,8 +697,9 @@ #define STRINGID_THESWAMPDISAPPEARED 695 #define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 696 #define STRINGID_HOSPITALITYRESTORATION 697 +#define STRINGID_ELECTROSHOCKCHARGING 698 -#define BATTLESTRINGS_COUNT 698 +#define BATTLESTRINGS_COUNT 699 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, @@ -756,6 +757,7 @@ #define B_MSG_TURN1_FREEZE_SHOCK 10 #define B_MSG_TURN1_SKY_DROP 11 #define B_MSG_TURN1_METEOR_BEAM 12 +#define B_MSG_TURN1_ELECTRO_SHOCK 13 // gMoveWeatherChangeStringIds #define B_MSG_STARTED_RAIN 0 diff --git a/include/constants/cries.h b/include/constants/cries.h index ddeee56d425a..03aa9c558e55 100644 --- a/include/constants/cries.h +++ b/include/constants/cries.h @@ -2025,6 +2025,7 @@ enum { CRY_APPLETUN, #if P_GEN_9_CROSS_EVOS CRY_DIPPLIN, + //CRY_HYDRAPPLE, #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN #if P_FAMILY_SILICOBRA @@ -2112,6 +2113,9 @@ enum { #endif //P_FAMILY_ARCTOVISH #if P_FAMILY_DURALUDON CRY_DURALUDON, +#if P_GEN_9_CROSS_EVOS + //CRY_ARCHALUDON, +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY CRY_DREEPY, @@ -2404,6 +2408,24 @@ enum { #if P_FAMILY_OGERPON CRY_OGERPON, #endif //P_FAMILY_OGERPON +#if P_FAMILY_GOUGING_FIRE + //CRY_GOUGING_FIRE, +#endif //P_FAMILY_GOUGING_FIRE +#if P_FAMILY_RAGING_BOLT + //CRY_RAGING_BOLT, +#endif //P_FAMILY_RAGING_BOLT +#if P_FAMILY_IRON_BOULDER + //CRY_IRON_BOULDER, +#endif //P_FAMILY_IRON_BOULDER +#if P_FAMILY_IRON_CROWN + //CRY_IRON_CROWN, +#endif //P_FAMILY_IRON_CROWN +#if P_FAMILY_TERAPAGOS + //CRY_TERAPAGOS, +#endif //P_FAMILY_TERAPAGOS +#if P_FAMILY_PECHARUNT + //CRY_PECHARUNT, +#endif //P_FAMILY_PECHARUNT CRY_COUNT, }; diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 872e5bbd3414..020a76664c31 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -3,7 +3,7 @@ #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 7 -#define EXPANSION_VERSION_PATCH 0 +#define EXPANSION_VERSION_PATCH 1 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. diff --git a/include/constants/field_specials.h b/include/constants/field_specials.h index 665940331365..1e08a47f95ee 100644 --- a/include/constants/field_specials.h +++ b/include/constants/field_specials.h @@ -62,7 +62,7 @@ #define DEPT_STORE_FLOORNUM_11F 14 #define DEPT_STORE_FLOORNUM_ROOFTOP 15 -// Lilycove Pokemon Trainer Fan Club +// Lilycove Pokémon Trainer Fan Club #define NUM_TRAINER_FAN_CLUB_MEMBERS 8 #define FANCLUB_GOT_FIRST_FANS 7 diff --git a/include/constants/global.h b/include/constants/global.h index f9b7241ef6eb..cb023efab356 100644 --- a/include/constants/global.h +++ b/include/constants/global.h @@ -9,9 +9,9 @@ // 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. -// In Gen 4 only, migrated Pokemon with Diamond, Pearl, or Platinum's ID show as "----------". +// In Gen 4 only, migrated Pokémon with Diamond, Pearl, or Platinum's ID show as "----------". // Gen 5 and up read Diamond, Pearl, or Platinum's ID as "Sinnoh". -// In Gen 4 and up, migrated Pokemon with HeartGold or SoulSilver's ID show the otherwise unused "Johto" string. +// In Gen 4 and up, migrated Pokémon with HeartGold or SoulSilver's ID show the otherwise unused "Johto" string. #define VERSION_SAPPHIRE 1 #define VERSION_RUBY 2 #define VERSION_EMERALD 3 diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index a54f569cd29e..0f364d2462cf 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -160,7 +160,6 @@ #define HOLD_EFFECT_COVERT_CLOAK 179 #define HOLD_EFFECT_LOADED_DICE 180 #define HOLD_EFFECT_BOOSTER_ENERGY 181 // Not implemented. -#define HOLD_EFFECT_MASK 183 // Gen2 hold effect #define HOLD_EFFECT_BERSERK_GENE 184 diff --git a/include/constants/pokedex.h b/include/constants/pokedex.h index ffbbb2eb18a8..c03b096f9add 100644 --- a/include/constants/pokedex.h +++ b/include/constants/pokedex.h @@ -1,7 +1,7 @@ #ifndef GUARD_CONSTANTS_POKEDEX_H #define GUARD_CONSTANTS_POKEDEX_H -// National Pokedex order. +// National Pokédex order // These constants are NOT disabled by P_GEN_X_POKEMON to keep pokedex_orders.h clean. enum { NATIONAL_DEX_NONE, @@ -1031,21 +1031,21 @@ enum { NATIONAL_DEX_MUNKIDORI, NATIONAL_DEX_FEZANDIPITI, NATIONAL_DEX_OGERPON, - NATIONAL_DEX_1018, - NATIONAL_DEX_1019, - NATIONAL_DEX_1020, - NATIONAL_DEX_1021, - NATIONAL_DEX_1022, - NATIONAL_DEX_1023, - NATIONAL_DEX_1024, - NATIONAL_DEX_1025, + NATIONAL_DEX_ARCHALUDON, + NATIONAL_DEX_HYDRAPPLE, + NATIONAL_DEX_GOUGING_FIRE, + NATIONAL_DEX_RAGING_BOLT, + NATIONAL_DEX_IRON_BOULDER, + NATIONAL_DEX_IRON_CROWN, + NATIONAL_DEX_TERAPAGOS, + NATIONAL_DEX_PECHARUNT, }; #define KANTO_DEX_COUNT NATIONAL_DEX_MEW #define JOHTO_DEX_COUNT NATIONAL_DEX_CELEBI #if P_GEN_9_POKEMON == TRUE - #define NATIONAL_DEX_COUNT NATIONAL_DEX_1025 + #define NATIONAL_DEX_COUNT NATIONAL_DEX_PECHARUNT #elif P_GEN_8_POKEMON == TRUE #define NATIONAL_DEX_COUNT NATIONAL_DEX_ENAMORUS #elif P_GEN_7_POKEMON == TRUE @@ -1062,7 +1062,7 @@ enum { #define POKEMON_SLOTS_NUMBER (NATIONAL_DEX_COUNT + 1) -// Hoenn Pokedex order +// Hoenn Pokédex order enum { HOENN_DEX_NONE, HOENN_DEX_TREECKO, diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 06da4a179ef1..4c98258adad9 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -1,7 +1,7 @@ #ifndef GUARD_CONSTANTS_POKEMON_H #define GUARD_CONSTANTS_POKEMON_H -// Pokemon types +// Pokémon types #define TYPE_NONE 255 #define TYPE_NORMAL 0 #define TYPE_FIGHTING 1 @@ -24,7 +24,7 @@ #define TYPE_FAIRY 18 #define NUMBER_OF_MON_TYPES 19 -// Pokemon egg groups +// Pokémon egg groups #define EGG_GROUP_NONE 0 #define EGG_GROUP_MONSTER 1 #define EGG_GROUP_WATER_1 2 @@ -44,7 +44,7 @@ #define EGG_GROUPS_PER_MON 2 -// Pokemon natures +// Pokémon natures #define NATURE_HARDY 0 #define NATURE_LONELY 1 #define NATURE_BRAVE 2 @@ -72,7 +72,7 @@ #define NATURE_QUIRKY 24 #define NUM_NATURES 25 -// Pokemon Stats +// Pokémon Stats #define STAT_HP 0 #define STAT_ATK 1 #define STAT_DEF 2 @@ -240,7 +240,7 @@ #define GROWTH_FAST 4 #define GROWTH_SLOW 5 -// Body colors for pokedex search +// Body colors for Pokédex search #define BODY_COLOR_RED 0 #define BODY_COLOR_BLUE 1 #define BODY_COLOR_YELLOW 2 @@ -316,7 +316,7 @@ #define MON_PIC_HEIGHT 64 #define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2) -// Most pokemon have 2 frames (a default and an alternate for their animation). +// Most Pokémon have 2 frames (a default and an alternate for their animation). // There are 4 exceptions: // - Deoxys has 2 frames, 1 for each form // - Spinda has 1 frame, presumably to avoid the work of animating its spots diff --git a/include/constants/species.h b/include/constants/species.h index bcac9ecbc8db..4f0e86738d62 100644 --- a/include/constants/species.h +++ b/include/constants/species.h @@ -1658,19 +1658,19 @@ #define SPECIES_OGERPON_CORNERSTONE_MASK_TERA GEN9_START + 135 #define SPECIES_URSALUNA_BLOODMOON GEN9_START + 136 // Indigo Disk -#define SPECIES_1018 GEN9_START + 137 -#define SPECIES_1019 GEN9_START + 138 -#define SPECIES_1020 GEN9_START + 139 -#define SPECIES_1021 GEN9_START + 140 -#define SPECIES_1022 GEN9_START + 141 -#define SPECIES_1023 GEN9_START + 142 -#define SPECIES_1024 SPECIES_1024_FORM_1 -#define SPECIES_1024_FORM_1 GEN9_START + 143 -#define SPECIES_1024_FORM_2 GEN9_START + 144 -#define SPECIES_1024_FORM_3 GEN9_START + 145 -#define SPECIES_1025 GEN9_START + 146 - -#define PLACEHOLDER_START SPECIES_1025 +#define SPECIES_ARCHALUDON GEN9_START + 137 +#define SPECIES_HYDRAPPLE GEN9_START + 138 +#define SPECIES_GOUGING_FIRE GEN9_START + 139 +#define SPECIES_RAGING_BOLT GEN9_START + 140 +#define SPECIES_IRON_BOULDER GEN9_START + 141 +#define SPECIES_IRON_CROWN GEN9_START + 142 +#define SPECIES_TERAPAGOS SPECIES_TERAPAGOS_NORMAL +#define SPECIES_TERAPAGOS_NORMAL GEN9_START + 143 +#define SPECIES_TERAPAGOS_TERASTAL GEN9_START + 144 +#define SPECIES_TERAPAGOS_STELLAR GEN9_START + 145 +#define SPECIES_PECHARUNT GEN9_START + 146 + +#define PLACEHOLDER_START SPECIES_PECHARUNT // XD: Gale of Darkness #define SPECIES_LUGIA_SHADOW PLACEHOLDER_START + 1 // Diamond & Pearl diff --git a/include/constants/tv.h b/include/constants/tv.h index 13ec88ecdcad..1b629fb03952 100644 --- a/include/constants/tv.h +++ b/include/constants/tv.h @@ -170,7 +170,7 @@ #define NUM_SECRET_BASE_FLAGS 32 // by definition, bitfield of 2 u16s -// TV Show states for Pokemon Contest Live Updates +// TV Show states for Pokémon Contest Live Updates #define CONTESTLIVE_STATE_INTRO 0 #define CONTESTLIVE_STATE_WON_BOTH_ROUNDS 1 #define CONTESTLIVE_STATE_BETTER_ROUND2 2 diff --git a/include/contest.h b/include/contest.h index 9f2fafaf25a2..8a3b6a3c6558 100644 --- a/include/contest.h +++ b/include/contest.h @@ -214,7 +214,7 @@ struct ContestantStatus u8 comboAppealBonus; u8 repeatJam; u8 nextTurnOrder; // turn position - u8 attentionLevel; // How much the Pokemon "stood out" + u8 attentionLevel; // How much the Pokémon "stood out" u8 contestantAnimTarget; }; diff --git a/include/crt0.h b/include/crt0.h index a4a5c7f79bc5..c60ed3b0b733 100644 --- a/include/crt0.h +++ b/include/crt0.h @@ -3,4 +3,6 @@ extern u32 IntrMain[]; +extern void ReInitializeEWRAM(); + #endif //GUARD_CRT0_H diff --git a/include/gba/defines.h b/include/gba/defines.h index fbe0a607065a..65dfc5e85509 100644 --- a/include/gba/defines.h +++ b/include/gba/defines.h @@ -6,8 +6,10 @@ #define TRUE 1 #define FALSE 0 -#define IWRAM_DATA __attribute__((section("iwram_data"))) -#define EWRAM_DATA __attribute__((section("ewram_data"))) +#define IWRAM_DATA __attribute__((section(".bss"))) +#define EWRAM_DATA __attribute__((section(".sbss"))) +#define IWRAM_INIT __attribute__((section(".iwram"))) +#define EWRAM_INIT __attribute__((section(".ewram"))) #define UNUSED __attribute__((unused)) #if MODERN diff --git a/include/global.h b/include/global.h index 84d5cafa7c62..4ec9407912cf 100644 --- a/include/global.h +++ b/include/global.h @@ -509,7 +509,7 @@ struct SaveBlock2 /*0x90*/ u8 filler_90[0x8]; /*0x98*/ struct Time localTimeOffset; /*0xA0*/ struct Time lastBerryTreeUpdate; - /*0xA8*/ u32 gcnLinkFlags; // Read by Pokemon Colosseum/XD + /*0xA8*/ u32 gcnLinkFlags; // Read by Pokémon Colosseum/XD /*0xAC*/ u32 encryptionKey; /*0xB0*/ struct PlayersApprentice playerApprentice; /*0xDC*/ struct Apprentice apprentices[APPRENTICE_COUNT]; diff --git a/include/graphics.h b/include/graphics.h index d8248575f8da..1c1ae1e52398 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -62,7 +62,7 @@ extern const u32 gBallGfx_Cherish[]; extern const u32 gBallPal_Cherish[]; extern const u32 gOpenPokeballGfx[]; -// pokemon gfx +// Pokémon gfx extern const u16 gMonIconPalettes[][16]; // pokeblock @@ -278,7 +278,7 @@ extern const u32 gBattleTerrainPalette_StadiumGlacia[]; extern const u32 gBattleTerrainPalette_StadiumDrake[]; extern const u32 gBattleTerrainPalette_StadiumWallace[]; -// pokedex +// Pokédex extern const u32 gPokedexInterface_Gfx[]; extern const u16 gPokedexBgHoenn_Pal[]; extern const u32 gPokedexMenu_Gfx[]; @@ -1911,7 +1911,7 @@ extern const u32 gBerryPalette_Rowap[]; extern const u32 gBerryPalette_Kee[]; extern const u32 gBerryPalette_Maranga[]; -//pokenav +//PokéNav extern const u16 gPokenavCondition_Pal[]; extern const u32 gPokenavCondition_Gfx[]; extern const u32 gPokenavCondition_Tilemap[]; @@ -3133,11 +3133,11 @@ extern const u32 gBattleAnimBgImage_Rainbow[]; extern const u32 gBattleAnimBGPalette_Rainbow[]; extern const u32 gBattleAnimBgTilemap_Rainbow[]; -// Pokedex Area Screen +// Pokédex Area Screen extern const u32 gPokedexAreaScreenAreaUnknown_Gfx[]; extern const u16 gPokedexAreaScreenAreaUnknown_Pal[]; -// Pokemon Storage System +// Pokémon Storage System extern const u32 gStorageSystemMenu_Gfx[]; extern const u16 gStorageSystemPartyMenu_Pal[]; extern const u32 gStorageSystemPartyMenu_Tilemap[]; @@ -3265,7 +3265,7 @@ extern const u32 gBerryCrush_Crusher_Gfx[]; extern const u16 gBerryCrush_Crusher_Pal[]; extern const u32 gBerryCrush_TextWindows_Tilemap[]; -// Pokenav +// PokéNav extern const u32 gPokenavMessageBox_Gfx[]; extern const u32 gPokenavMessageBox_Tilemap[]; extern const u16 gPokenavMessageBox_Pal[]; diff --git a/include/pokemon.h b/include/pokemon.h index 6ce793a19e13..87d74b766c8a 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -513,6 +513,14 @@ struct Ability { u8 name[ABILITY_NAME_LENGTH + 1]; const u8 *description; + s8 aiRating; + u8 cantBeCopied:1; // cannot be copied by Role Play or Doodle + u8 cantBeSwapped:1; // cannot be swapped with Skill Swap or Wandering Spirit + u8 cantBeTraced:1; // cannot be copied by Trace - same as cantBeCopied except for Wonder Guard + u8 cantBeSuppressed:1; // cannot be negated by Gastro Acid or Neutralizing Gas + u8 cantBeOverwritten:1; // cannot be overwritten by Entrainment, Worry Seed or Simple Beam (but can be by Mummy) - same as cantBeSuppressed except for Truant + u8 breakable:1; // can be bypassed by Mold Breaker and clones + u8 failsOnImposter:1; // doesn't work on an Imposter mon; when can we actually use this? }; #define SPINDA_SPOT_WIDTH 16 diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h index b313b59d9b72..f56c3aca64e5 100755 --- a/include/pokemon_summary_screen.h +++ b/include/pokemon_summary_screen.h @@ -17,7 +17,7 @@ void ShowPokemonSummaryScreenHandleDeoxys(u8 mode, struct BoxPokemon *mons, u8 m u8 GetMoveSlotToReplace(void); void SummaryScreen_SetAnimDelayTaskId(u8 taskId); -// The Pokemon Summary Screen can operate in different modes. Certain features, +// The Pokémon Summary Screen can operate in different modes. Certain features, // such as move re-ordering, are available in the different modes. enum PokemonSummaryScreenMode { diff --git a/include/pokenav.h b/include/pokenav.h index c6a8bb253e88..174c338e270f 100644 --- a/include/pokenav.h +++ b/include/pokenav.h @@ -65,8 +65,8 @@ struct PokenavMonList enum { POKENAV_MODE_NORMAL, // Chosen from Start menu. - POKENAV_MODE_FORCE_CALL_READY, // Pokenav tutorial before calling Mr. Stone - POKENAV_MODE_FORCE_CALL_EXIT, // Pokenav tutorial after calling Mr. Stone + POKENAV_MODE_FORCE_CALL_READY, // PokéNav tutorial before calling Mr. Stone + POKENAV_MODE_FORCE_CALL_EXIT, // PokéNav tutorial after calling Mr. Stone }; enum @@ -232,8 +232,8 @@ enum [CHECK_PAGE_INTRO_2] = gText_MatchCall##name##_Intro2} -// Pokenav Function IDs -// Indices into the LoopedTask tables for each of the main Pokenav features +// PokéNav Function IDs +// Indices into the LoopedTask tables for each of the main PokéNav features enum RegionMapFuncIds { diff --git a/include/random.h b/include/random.h index a13b28674f7a..8768f7c6dd18 100644 --- a/include/random.h +++ b/include/random.h @@ -177,6 +177,7 @@ enum RandomTag RNG_QUICK_DRAW, RNG_QUICK_CLAW, RNG_TRACE, + RNG_FICKLE_BEAM, }; #define RandomWeighted(tag, ...) \ diff --git a/include/strings.h b/include/strings.h index 8a26819c5a55..bb4c3f9de211 100644 --- a/include/strings.h +++ b/include/strings.h @@ -524,7 +524,7 @@ extern const u8 gText_Speed[]; extern const u8 gText_Dash[]; extern const u8 gText_Plus[]; -//pokedex text +//Pokédex text extern const u8 gText_CryOf[]; extern const u8 gText_SizeComparedTo[]; extern const u8 gText_PokedexRegistration[]; @@ -1130,7 +1130,7 @@ extern const u8 gTrickHouse_Mechadoll_Six2[]; extern const u8 gTrickHouse_Mechadoll_Seven2[]; extern const u8 gTrickHouse_Mechadoll_Eight2[]; -// Pokedex strings +// Pokédex strings extern const u8 gText_SearchForPkmnBasedOnParameters[]; extern const u8 gText_SwitchPokedexListings[]; extern const u8 gText_ReturnToPokedex[]; @@ -2897,7 +2897,7 @@ extern const u8 gText_WantToPlayAgain[]; extern const u8 gText_CommunicationStandby3[]; extern const u8 gText_SomeoneDroppedOut[]; -// Pokemon jump +// Pokémon jump extern const u8 gText_WantToPlayAgain2[]; extern const u8 gText_SomeoneDroppedOut2[]; extern const u8 gText_CommunicationStandby4[]; @@ -2972,7 +2972,7 @@ extern const u8 gText_CutenessContest[]; extern const u8 gText_SmartnessContest[]; extern const u8 gText_ToughnessContest[]; -// Pokenav Match Call +// PokéNav Match Call extern const u8 gText_CallCantBeMadeHere[]; extern const u8 gText_NumberRegistered[]; extern const u8 gText_NumberOfBattles[]; @@ -2982,7 +2982,7 @@ extern const u8 gText_Call[]; extern const u8 gText_Check[]; extern const u8 gText_Cancel6[]; -// Pokenav Menu Handler +// PokéNav Menu Handler extern const u8 gText_CheckMapOfHoenn[]; extern const u8 gText_CheckPokemonInDetail[]; extern const u8 gText_CallRegisteredTrainer[]; @@ -2999,7 +2999,7 @@ extern const u8 gText_FindToughPokemon[]; extern const u8 gText_ReturnToConditionMenu[]; extern const u8 gText_NoRibbonWinners[]; -// Pokenav +// PokéNav extern const u8 gText_NumberIndex[]; extern const u8 gText_RibbonsF700[]; diff --git a/include/test/test.h b/include/test/test.h index 74e10ec69123..790563e77227 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -166,6 +166,9 @@ struct Benchmark { s32 ticks; }; static inline void BenchmarkStart(void) { gTestRunnerState.inBenchmark = TRUE; + // Wait for a v-blank so that comparing two benchmarks is not affected + // by the v-count (different numbers of IRQs may run). + VBlankIntrWait(); REG_TM3CNT = (TIMER_ENABLE | TIMER_64CLK) << 16; } diff --git a/ld_script.ld b/ld_script.ld index 642480d35d83..e9cbae895769 100644 --- a/ld_script.ld +++ b/ld_script.ld @@ -13,19 +13,35 @@ MEMORY SECTIONS { - ewram 0x2000000 (NOLOAD) : + .ewram ORIGIN(EWRAM) : AT (__ewram_lma) + ALIGN(4) + { + __ewram_start = .; + *(.ewram*) + __ewram_end = .; + } > EWRAM + + .ewram.sbss (NOLOAD) : ALIGN(4) { INCLUDE "sym_ewram.ld" - src/*.o(ewram_data); - gflib/*.o(ewram_data); + src/*.o(.sbss); + gflib/*.o(.sbss); *libc.a:impure.o(.data); *libc.a:locale.o(.data); *libc.a:mallocr.o(.data); } > EWRAM - iwram 0x3000000 (NOLOAD) : + .iwram ORIGIN(IWRAM) : AT (__iwram_lma) + ALIGN(4) + { + __iwram_start = .; + *(.iwram*); + __iwram_end = .; + } > IWRAM + + .iwram.bss (NOLOAD) : ALIGN(4) { /* .bss starts at 0x3000000 */ @@ -1324,6 +1340,20 @@ SECTIONS { data/*.o(.rodata); } > ROM = 0 + .data.iwram : + ALIGN(4) + { + __iwram_lma = .; + . = . + (__iwram_end - __iwram_start); + } > ROM = 0 + + .data.ewram : + ALIGN(4) + { + __ewram_lma = .; + . = . + (__ewram_end - __ewram_start); + } > ROM = 0 + __rom_end = .; /* DWARF debug sections. diff --git a/ld_script_modern.ld b/ld_script_modern.ld index f3bf7b6798df..fd35a1ca31d8 100644 --- a/ld_script_modern.ld +++ b/ld_script_modern.ld @@ -12,15 +12,32 @@ MEMORY } SECTIONS { - ewram 0x2000000 (NOLOAD) : + + + .ewram ORIGIN(EWRAM) : AT (__ewram_lma) ALIGN(4) { - src/*.o(ewram_data); - gflib/*.o(ewram_data); + __ewram_start = .; + *(.ewram*) + __ewram_end = .; + } > EWRAM + .ewram.sbss (NOLOAD) : + ALIGN(4) + { + src/*.o(.sbss); + gflib/*.o(.sbss); } > EWRAM - iwram 0x3000000 (NOLOAD) : + .iwram ORIGIN(IWRAM) : AT (__iwram_lma) + ALIGN(4) + { + __iwram_start = .; + *(.iwram*); + __iwram_end = .; + } > IWRAM + + .iwram.bss (NOLOAD) : ALIGN(4) { src/*.o(.bss); @@ -38,9 +55,8 @@ SECTIONS { } > IWRAM /* BEGIN ROM DATA */ - . = 0x8000000; - .text : + .text ORIGIN(ROM) : ALIGN(4) { src/rom_header.o(.text*); @@ -125,6 +141,20 @@ SECTIONS { src/graphics.o(.rodata); } > ROM =0 + .data.iwram : + ALIGN(4) + { + __iwram_lma = .; + . = . + (__iwram_end - __iwram_start); + } > ROM = 0 + + .data.ewram : + ALIGN(4) + { + __ewram_lma = .; + . = . + (__ewram_end - __ewram_start); + } > ROM = 0 + __rom_end = .; /* DWARF debug sections. diff --git a/ld_script_test.ld b/ld_script_test.ld index b86302f8cb9a..ec99609a7e6d 100644 --- a/ld_script_test.ld +++ b/ld_script_test.ld @@ -12,15 +12,32 @@ MEMORY } SECTIONS { - ewram 0x2000000 (NOLOAD) : + + .ewram ORIGIN(EWRAM) : AT (__ewram_lma) + ALIGN(4) + { + __ewram_start = .; + *(.ewram*) + __ewram_end = .; + } > EWRAM + + .ewram.sbss (NOLOAD) : ALIGN(4) { - src/*.o(ewram_data); - gflib/*.o(ewram_data); - test/*.o(ewram_data); + src/*.o(.sbss); + gflib/*.o(.sbss); + test/*.o(.sbss); } > EWRAM - iwram 0x3000000 (NOLOAD) : + .iwram ORIGIN(IWRAM) : AT (__iwram_lma) + ALIGN(4) + { + __iwram_start = .; + *(.iwram*); + __iwram_end = .; + } > IWRAM + + .iwram.sbss (NOLOAD) : ALIGN(4) { src/*.o(.bss); @@ -97,6 +114,20 @@ SECTIONS { src/libisagbprn.o(.rodata); } > ROM =0 + .data.iwram : + ALIGN(4) + { + __iwram_lma = .; + . = . + (__iwram_end - __iwram_start); + } > ROM = 0 + + .data.ewram : + ALIGN(4) + { + __ewram_lma = .; + . = . + (__ewram_end - __ewram_start); + } > ROM = 0 + tests : ALIGN(4) { @@ -109,6 +140,12 @@ SECTIONS { __rom_end = .; + dacs 0x9FFC000 : + ALIGN(4) + { + test/*.o(.dacs); + } > ROM =0 + /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 25b0b96414a7..ae06cdfb5155 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2153,8 +2153,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_ROLE_PLAY: if (aiData->abilities[battlerAtk] == aiData->abilities[battlerDef] || aiData->abilities[battlerDef] == ABILITY_NONE - || IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) - || IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef])) + || gAbilities[aiData->abilities[battlerAtk]].cantBeSuppressed + || gAbilities[aiData->abilities[battlerDef]].cantBeCopied) ADJUST_SCORE(-10); else if (IsAbilityOfRating(aiData->abilities[battlerAtk], 5)) ADJUST_SCORE(-4); @@ -2183,25 +2183,26 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_SKILL_SWAP: if (aiData->abilities[battlerAtk] == ABILITY_NONE || aiData->abilities[battlerDef] == ABILITY_NONE - || IsSkillSwapBannedAbility(aiData->abilities[battlerAtk]) || IsSkillSwapBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerAtk]].cantBeSwapped + || gAbilities[aiData->abilities[battlerDef]].cantBeSwapped || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; case EFFECT_WORRY_SEED: if (aiData->abilities[battlerDef] == ABILITY_INSOMNIA - || IsWorrySeedBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; case EFFECT_GASTRO_ACID: if (gStatuses3[battlerDef] & STATUS3_GASTRO_ACID - || IsGastroAcidBannedAbility(aiData->abilities[battlerDef])) + || gAbilities[aiData->abilities[battlerDef]].cantBeSuppressed) ADJUST_SCORE(-10); break; case EFFECT_ENTRAINMENT: if (aiData->abilities[battlerAtk] == ABILITY_NONE - || IsEntrainmentBannedAbilityAttacker(aiData->abilities[battlerAtk]) - || IsEntrainmentBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerAtk]].cantBeCopied + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerAtk] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -2209,7 +2210,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_SIMPLE_BEAM: if (aiData->abilities[battlerDef] == ABILITY_SIMPLE - || IsSimpleBeamBannedAbility(aiData->abilities[battlerDef]) + || gAbilities[aiData->abilities[battlerDef]].cantBeOverwritten || aiData->holdEffects[battlerDef] == HOLD_EFFECT_ABILITY_SHIELD) ADJUST_SCORE(-10); break; @@ -2730,8 +2731,8 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) u32 atkPartnerAbility = aiData->abilities[BATTLE_PARTNER(battlerAtk)]; u32 atkPartnerHoldEffect = aiData->holdEffects[BATTLE_PARTNER(battlerAtk)]; bool32 partnerProtecting = (gBattleMoves[aiData->partnerMove].effect == EFFECT_PROTECT); - bool32 attackerHasBadAbility = (GetAbilityRating(aiData->abilities[battlerAtk]) < 0); - bool32 partnerHasBadAbility = (GetAbilityRating(atkPartnerAbility) < 0); + bool32 attackerHasBadAbility = (gAbilities[aiData->abilities[battlerAtk]].aiRating < 0); + bool32 partnerHasBadAbility = (gAbilities[atkPartnerAbility].aiRating < 0); u32 predictedMove = aiData->predictedMoves[battlerDef]; SetTypeBeforeUsingMove(move, battlerAtk); @@ -4377,8 +4378,8 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score } break; case EFFECT_ROLE_PLAY: - if (!IsRolePlayDoodleBannedAbilityAttacker(aiData->abilities[battlerAtk]) - && !IsRolePlayDoodleBannedAbility(aiData->abilities[battlerDef]) + if (!gAbilities[aiData->abilities[battlerAtk]].cantBeSuppressed + && !gAbilities[aiData->abilities[battlerDef]].cantBeCopied && !IsAbilityOfRating(aiData->abilities[battlerAtk], 5) && IsAbilityOfRating(aiData->abilities[battlerDef], 5)) ADJUST_SCORE(2); @@ -4444,7 +4445,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score } break; case EFFECT_SKILL_SWAP: - if (GetAbilityRating(aiData->abilities[battlerDef]) > GetAbilityRating(aiData->abilities[battlerAtk])) + if (gAbilities[aiData->abilities[battlerDef]].aiRating > gAbilities[aiData->abilities[battlerAtk]].aiRating) ADJUST_SCORE(1); break; case EFFECT_WORRY_SEED: @@ -4454,7 +4455,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(2); break; case EFFECT_ENTRAINMENT: - if (IsAbilityOfRating(aiData->abilities[battlerDef], 5) || GetAbilityRating(aiData->abilities[battlerAtk]) <= 0) + if (IsAbilityOfRating(aiData->abilities[battlerDef], 5) || gAbilities[aiData->abilities[battlerAtk]].aiRating <= 0) { if (aiData->abilities[battlerDef] != aiData->abilities[battlerAtk] && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID)) ADJUST_SCORE(2); @@ -4740,7 +4741,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(3); break; case EFFECT_HEAL_BLOCK: - if (AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER && predictedMove != MOVE_NONE && IsHealingMoveEffect(gBattleMoves[predictedMove].effect)) + if (AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER && predictedMove != MOVE_NONE && IsHealingMove(predictedMove)) ADJUST_SCORE(3); // Try to cancel healing move else if (HasHealingEffect(battlerDef) || aiData->holdEffects[battlerDef] == HOLD_EFFECT_LEFTOVERS || (aiData->holdEffects[battlerDef] == HOLD_EFFECT_BLACK_SLUDGE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON))) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 5f96ef1e34ee..43450089c409 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -249,7 +249,7 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler, bool32 emitResult) if (GetBattlerAbility(GetBattlerAtPosition(opposingPosition)) != ABILITY_WONDER_GUARD) return FALSE; - // Check if Pokemon has a super effective move. + // Check if Pokémon has a super effective move. for (opposingBattler = GetBattlerAtPosition(opposingPosition), i = 0; i < MAX_MON_MOVES; i++) { move = gBattleMons[battler].moves[i]; @@ -268,7 +268,7 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler, bool32 emitResult) else party = gEnemyParty; - // Find a Pokemon in the party that has a super effective move. + // Find a Pokémon in the party that has a super effective move. for (i = firstId; i < lastId; i++) { if (!IsValidForBattle(&party[i])) @@ -295,7 +295,7 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler, bool32 emitResult) } } - return FALSE; // There is not a single Pokemon in the party that has a super effective move against a mon with Wonder Guard. + return FALSE; // There is not a single Pokémon in the party that has a super effective move against a mon with Wonder Guard. } static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler, bool32 emitResult) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index e11700dba903..ed2180b98627 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -35,267 +35,6 @@ static u32 AI_GetEffectiveness(uq4_12_t multiplier); // Const Data -static const s8 sAiAbilityRatings[ABILITIES_COUNT] = -{ - [ABILITY_ADAPTABILITY] = 8, - [ABILITY_AFTERMATH] = 5, - [ABILITY_AERILATE] = 8, - [ABILITY_AIR_LOCK] = 5, - [ABILITY_ANALYTIC] = 5, - [ABILITY_ANGER_POINT] = 4, - [ABILITY_ANTICIPATION] = 2, - [ABILITY_ARENA_TRAP] = 9, - [ABILITY_AROMA_VEIL] = 3, - [ABILITY_AURA_BREAK] = 3, - [ABILITY_BAD_DREAMS] = 4, - [ABILITY_BATTERY] = 0, - [ABILITY_BATTLE_ARMOR] = 2, - [ABILITY_BATTLE_BOND] = 6, - [ABILITY_BEAST_BOOST] = 7, - [ABILITY_BERSERK] = 5, - [ABILITY_BIG_PECKS] = 1, - [ABILITY_BLAZE] = 5, - [ABILITY_BULLETPROOF] = 7, - [ABILITY_CHEEK_POUCH] = 4, - [ABILITY_CHLOROPHYLL] = 6, - [ABILITY_CLEAR_BODY] = 4, - [ABILITY_CLOUD_NINE] = 5, - [ABILITY_COLOR_CHANGE] = 2, - [ABILITY_COMATOSE] = 6, - [ABILITY_COMPETITIVE] = 5, - [ABILITY_COMPOUND_EYES] = 7, - [ABILITY_CONTRARY] = 8, - [ABILITY_CORROSION] = 5, - [ABILITY_CURSED_BODY] = 4, - [ABILITY_CUTE_CHARM] = 2, - [ABILITY_DAMP] = 2, - [ABILITY_DANCER] = 5, - [ABILITY_DARK_AURA] = 6, - [ABILITY_DAZZLING] = 5, - [ABILITY_DEFEATIST] = -1, - [ABILITY_DEFIANT] = 5, - [ABILITY_DELTA_STREAM] = 10, - [ABILITY_DESOLATE_LAND] = 10, - [ABILITY_DISGUISE] = 8, - [ABILITY_DOWNLOAD] = 7, - [ABILITY_DRIZZLE] = 9, - [ABILITY_DROUGHT] = 9, - [ABILITY_DRY_SKIN] = 6, - [ABILITY_EARLY_BIRD] = 4, - [ABILITY_EFFECT_SPORE] = 4, - [ABILITY_ELECTRIC_SURGE] = 8, - [ABILITY_EMERGENCY_EXIT] = 3, - [ABILITY_FAIRY_AURA] = 6, - [ABILITY_FILTER] = 6, - [ABILITY_FLAME_BODY] = 4, - [ABILITY_FLARE_BOOST] = 5, - [ABILITY_FLASH_FIRE] = 6, - [ABILITY_FLOWER_GIFT] = 4, - [ABILITY_FLOWER_VEIL] = 0, - [ABILITY_FLUFFY] = 5, - [ABILITY_FORECAST] = 6, - [ABILITY_FOREWARN] = 2, - [ABILITY_FRIEND_GUARD] = 0, - [ABILITY_FRISK] = 3, - [ABILITY_FULL_METAL_BODY] = 4, - [ABILITY_FUR_COAT] = 7, - [ABILITY_GALE_WINGS] = 6, - [ABILITY_GALVANIZE] = 8, - [ABILITY_GLUTTONY] = 3, - [ABILITY_GOOEY] = 5, - [ABILITY_GRASS_PELT] = 2, - [ABILITY_GRASSY_SURGE] = 8, - [ABILITY_GUTS] = 6, - [ABILITY_HARVEST] = 5, - [ABILITY_HEALER] = 0, - [ABILITY_HEATPROOF] = 5, - [ABILITY_HEAVY_METAL] = -1, - [ABILITY_HONEY_GATHER] = 0, - [ABILITY_HUGE_POWER] = 10, - [ABILITY_HUSTLE] = 7, - [ABILITY_HYDRATION] = 4, - [ABILITY_HYPER_CUTTER] = 3, - [ABILITY_ICE_BODY] = 3, - [ABILITY_ILLUMINATE] = 0, - [ABILITY_ILLUSION] = 8, - [ABILITY_IMMUNITY] = 4, - [ABILITY_IMPOSTER] = 9, - [ABILITY_INFILTRATOR] = 6, - [ABILITY_INNARDS_OUT] = 5, - [ABILITY_INNER_FOCUS] = 2, - [ABILITY_INSOMNIA] = 4, - [ABILITY_INTIMIDATE] = 7, - [ABILITY_IRON_BARBS] = 6, - [ABILITY_IRON_FIST] = 6, - [ABILITY_JUSTIFIED] = 4, - [ABILITY_KEEN_EYE] = 1, - [ABILITY_KLUTZ] = -1, - [ABILITY_LEAF_GUARD] = 2, - [ABILITY_LEVITATE] = 7, - [ABILITY_LIGHT_METAL] = 2, - [ABILITY_LIGHTNING_ROD] = 7, - [ABILITY_LIMBER] = 3, - [ABILITY_LIQUID_OOZE] = 3, - [ABILITY_LIQUID_VOICE] = 5, - [ABILITY_LONG_REACH] = 3, - [ABILITY_MAGIC_BOUNCE] = 9, - [ABILITY_MAGIC_GUARD] = 9, - [ABILITY_MAGICIAN] = 3, - [ABILITY_MAGMA_ARMOR] = 1, - [ABILITY_MAGNET_PULL] = 9, - [ABILITY_MARVEL_SCALE] = 5, - [ABILITY_MEGA_LAUNCHER] = 7, - [ABILITY_MERCILESS] = 4, - [ABILITY_MINUS] = 0, - [ABILITY_MISTY_SURGE] = 8, - [ABILITY_MOLD_BREAKER] = 7, - [ABILITY_MOODY] = 10, - [ABILITY_MOTOR_DRIVE] = 6, - [ABILITY_MOXIE] = 7, - [ABILITY_MULTISCALE] = 8, - [ABILITY_MULTITYPE] = 8, - [ABILITY_MUMMY] = 5, - [ABILITY_NATURAL_CURE] = 7, - [ABILITY_NEUROFORCE] = 6, - [ABILITY_NO_GUARD] = 8, - [ABILITY_NORMALIZE] = -1, - [ABILITY_OBLIVIOUS] = 2, - [ABILITY_OVERCOAT] = 5, - [ABILITY_OVERGROW] = 5, - [ABILITY_OWN_TEMPO] = 3, - [ABILITY_PARENTAL_BOND] = 10, - [ABILITY_PICKUP] = 1, - [ABILITY_PICKPOCKET] = 3, - [ABILITY_PIXILATE] = 8, - [ABILITY_PLUS] = 0, - [ABILITY_POISON_HEAL] = 8, - [ABILITY_POISON_POINT] = 4, - [ABILITY_POISON_TOUCH] = 4, - [ABILITY_POWER_CONSTRUCT] = 10, - [ABILITY_POWER_OF_ALCHEMY] = 0, - [ABILITY_PRANKSTER] = 8, - [ABILITY_PRESSURE] = 5, - [ABILITY_PRIMORDIAL_SEA] = 10, - [ABILITY_PRISM_ARMOR] = 6, - [ABILITY_PROTEAN] = 8, - [ABILITY_PSYCHIC_SURGE] = 8, - [ABILITY_PURE_POWER] = 10, - [ABILITY_QUEENLY_MAJESTY] = 6, - [ABILITY_QUICK_FEET] = 5, - [ABILITY_RAIN_DISH] = 3, - [ABILITY_RATTLED] = 3, - [ABILITY_RECEIVER] = 0, - [ABILITY_RECKLESS] = 6, - [ABILITY_REFRIGERATE] = 8, - [ABILITY_REGENERATOR] = 8, - [ABILITY_RIVALRY] = 1, - [ABILITY_RKS_SYSTEM] = 8, - [ABILITY_ROCK_HEAD] = 5, - [ABILITY_ROUGH_SKIN] = 6, - [ABILITY_RUN_AWAY] = 0, - [ABILITY_SAND_FORCE] = 4, - [ABILITY_SAND_RUSH] = 6, - [ABILITY_SAND_STREAM] = 9, - [ABILITY_SAND_VEIL] = 3, - [ABILITY_SAP_SIPPER] = 7, - [ABILITY_SCHOOLING] = 6, - [ABILITY_SCRAPPY] = 6, - [ABILITY_SERENE_GRACE] = 8, - [ABILITY_SHADOW_SHIELD] = 8, - [ABILITY_SHADOW_TAG] = 10, - [ABILITY_SHED_SKIN] = 7, - [ABILITY_SHEER_FORCE] = 8, - [ABILITY_SHELL_ARMOR] = 2, - [ABILITY_SHIELD_DUST] = 5, - [ABILITY_SHIELDS_DOWN] = 6, - [ABILITY_SIMPLE] = 8, - [ABILITY_SKILL_LINK] = 7, - [ABILITY_SLOW_START] = -2, - [ABILITY_SLUSH_RUSH] = 5, - [ABILITY_SNIPER] = 3, - [ABILITY_SNOW_CLOAK] = 3, - [ABILITY_SNOW_WARNING] = 8, - [ABILITY_SOLAR_POWER] = 3, - [ABILITY_SOLID_ROCK] = 6, - [ABILITY_SOUL_HEART] = 7, - [ABILITY_SOUNDPROOF] = 4, - [ABILITY_SPEED_BOOST] = 9, - [ABILITY_STAKEOUT] = 6, - [ABILITY_STALL] = -1, - [ABILITY_STAMINA] = 6, - [ABILITY_STANCE_CHANGE] = 10, - [ABILITY_STATIC] = 4, - [ABILITY_STEADFAST] = 2, - [ABILITY_STEELWORKER] = 6, - [ABILITY_STENCH] = 1, - [ABILITY_STICKY_HOLD] = 3, - [ABILITY_STORM_DRAIN] = 7, - [ABILITY_STRONG_JAW] = 6, - [ABILITY_STURDY] = 6, - [ABILITY_SUCTION_CUPS] = 2, - [ABILITY_SUPER_LUCK] = 3, - [ABILITY_SURGE_SURFER] = 4, - [ABILITY_SWARM] = 5, - [ABILITY_SWEET_VEIL] = 4, - [ABILITY_SWIFT_SWIM] = 6, - [ABILITY_SYMBIOSIS] = 0, - [ABILITY_SYNCHRONIZE] = 4, - [ABILITY_TANGLED_FEET] = 2, - [ABILITY_TANGLING_HAIR] = 5, - [ABILITY_TECHNICIAN] = 8, - [ABILITY_TELEPATHY] = 0, - [ABILITY_TERAVOLT] = 7, - [ABILITY_THICK_FAT] = 7, - [ABILITY_TINTED_LENS] = 7, - [ABILITY_TORRENT] = 5, - [ABILITY_TOXIC_BOOST] = 6, - [ABILITY_TOUGH_CLAWS] = 7, - [ABILITY_TRACE] = 6, - [ABILITY_TRIAGE] = 7, - [ABILITY_TRUANT] = -2, - [ABILITY_TURBOBLAZE] = 7, - [ABILITY_UNAWARE] = 6, - [ABILITY_UNBURDEN] = 7, - [ABILITY_UNNERVE] = 3, - [ABILITY_VICTORY_STAR] = 6, - [ABILITY_VITAL_SPIRIT] = 4, - [ABILITY_VOLT_ABSORB] = 7, - [ABILITY_WATER_ABSORB] = 7, - [ABILITY_WATER_BUBBLE] = 8, - [ABILITY_WATER_COMPACTION] = 4, - [ABILITY_WATER_VEIL] = 4, - [ABILITY_WEAK_ARMOR] = 2, - [ABILITY_WHITE_SMOKE] = 4, - [ABILITY_WIMP_OUT] = 3, - [ABILITY_WONDER_GUARD] = 10, - [ABILITY_WONDER_SKIN] = 4, - [ABILITY_ZEN_MODE] = -1, - [ABILITY_INTREPID_SWORD] = 3, - [ABILITY_DAUNTLESS_SHIELD] = 3, - [ABILITY_BALL_FETCH] = 0, - [ABILITY_COTTON_DOWN] = 3, - [ABILITY_MIRROR_ARMOR] = 6, - [ABILITY_GULP_MISSILE] = 3, - [ABILITY_STALWART] = 2, - [ABILITY_PROPELLER_TAIL] = 2, - [ABILITY_STEAM_ENGINE] = 3, - [ABILITY_PUNK_ROCK] = 2, - [ABILITY_SAND_SPIT] = 5, - [ABILITY_ICE_SCALES] = 7, - [ABILITY_RIPEN] = 4, - [ABILITY_ICE_FACE] = 4, - [ABILITY_POWER_SPOT] = 2, - [ABILITY_MIMICRY] = 2, - [ABILITY_SCREEN_CLEANER] = 3, - [ABILITY_NEUTRALIZING_GAS] = 5, - [ABILITY_HUNGER_SWITCH] = 2, - [ABILITY_PASTEL_VEIL] = 4, - [ABILITY_STEELY_SPIRIT] = 2, - [ABILITY_PERISH_BODY] = -1, - [ABILITY_WANDERING_SPIRIT] = 2, - [ABILITY_GORILLA_TACTICS] = 4, -}; - static const u16 sEncouragedEncoreEffects[] = { EFFECT_DREAM_EATER, @@ -710,11 +449,14 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes gBattleStruct->zmove.baseMoves[battlerAtk] = move; gBattleStruct->zmove.active = TRUE; } + else if (gBattleMoves[move].effect == EFFECT_PHOTON_GEYSER) + gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) == BATTLE_CATEGORY_PHYSICAL); + + if (gBattleMoves[move].effect == EFFECT_NATURE_POWER) + move = GetNaturePowerMove(); gBattleStruct->dynamicMoveType = 0; - if (move == MOVE_NATURE_POWER) - move = GetNaturePowerMove(); SetTypeBeforeUsingMove(move, battlerAtk); GET_MOVE_TYPE(move, moveType); @@ -826,6 +568,7 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes // convert multiper to AI_EFFECTIVENESS_xX *typeEffectiveness = AI_GetEffectiveness(effectivenessMultiplier); + gBattleStruct->swapDamageCategory = FALSE; gBattleStruct->zmove.active = FALSE; gBattleStruct->zmove.baseMoves[battlerAtk] = MOVE_NONE; return dmg; @@ -2030,28 +1773,9 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef) return FALSE; } -bool32 IsHealingMoveEffect(u32 effect) +bool32 IsHealingMove(u32 move) { - switch (effect) - { - case EFFECT_RESTORE_HP: - case EFFECT_MORNING_SUN: - case EFFECT_SYNTHESIS: - case EFFECT_MOONLIGHT: - case EFFECT_SOFTBOILED: - case EFFECT_ROOST: - case EFFECT_SWALLOW: - case EFFECT_WISH: - case EFFECT_HEALING_WISH: - case EFFECT_HEAL_PULSE: - case EFFECT_REST: - case EFFECT_JUNGLE_HEALING: - case EFFECT_ABSORB: - case EFFECT_DREAM_EATER: - return TRUE; - default: - return FALSE; - } + return gBattleMoves[move].healBlockBanned; } bool32 HasHealingEffect(u32 battlerId) @@ -2061,7 +1785,7 @@ bool32 HasHealingEffect(u32 battlerId) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && IsHealingMoveEffect(gBattleMoves[moves[i]].effect)) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && IsHealingMove(moves[i])) return TRUE; } @@ -3485,16 +3209,11 @@ bool32 SideHasMoveCategory(u32 battlerId, u32 category) bool32 IsAbilityOfRating(u32 ability, s8 rating) { - if (sAiAbilityRatings[ability] >= rating) + if (gAbilities[ability].aiRating >= rating) return TRUE; return FALSE; } -s8 GetAbilityRating(u32 ability) -{ - return sAiAbilityRatings[ability]; -} - static const u16 sRecycleEncouragedItems[] = { ITEM_CHESTO_BERRY, diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c index 5f52d6cd675a..7caac0a869c7 100644 --- a/src/battle_anim_mon_movement.c +++ b/src/battle_anim_mon_movement.c @@ -543,7 +543,7 @@ static void SlideMonToOriginalPos_Step(struct Sprite *sprite) } // Linearly translates a mon to a target offset. The horizontal offset -// is mirrored for the opponent's pokemon, and the vertical offset +// is mirrored for the opponent's Pokémon, and the vertical offset // is only mirrored if arg 3 is set to 1. // arg 0: 0 = attacker, 1 = target // arg 1: target x pixel offset diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index 891fa402f5b8..b01f59a260cb 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -52,7 +52,7 @@ const struct UCoords8 sBattlerCoords[][MAX_BATTLERS_COUNT] = }, }; -// Placeholders for pokemon sprites to be created for a move animation effect (e.g. Role Play / Snatch) +// Placeholders for Pokémon sprites to be created for a move animation effect (e.g. Role Play / Snatch) #define TAG_MOVE_EFFECT_MON_1 55125 #define TAG_MOVE_EFFECT_MON_2 55126 @@ -2052,7 +2052,7 @@ u8 GetBattlerSpriteBGPriorityRank(u8 battlerId) return 1; } -// Create pokemon sprite to be used for a move animation effect (e.g. Role Play / Snatch) +// Create Pokémon sprite to be used for a move animation effect (e.g. Role Play / Snatch) u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, bool8 isShiny, u32 battlerId) { u8 spriteId; diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 10f0951950b2..ec5945d63377 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -226,16 +226,16 @@ static u16 GetPrevBall(u16 ballId) return gBagPockets[BALLS_POCKET].itemSlots[i].itemId; } -static u16 GetNextBall(u16 ballId) +static u32 GetNextBall(u32 ballId) { - u16 ballNext = 0; + u32 ballNext = ITEM_NONE; s32 i; CompactItemsInBagPocket(&gBagPockets[BALLS_POCKET]); - for (i = 0; i < gBagPockets[BALLS_POCKET].capacity; i++) + for (i = 1; i < gBagPockets[BALLS_POCKET].capacity; i++) { - if (ballId == gBagPockets[BALLS_POCKET].itemSlots[i].itemId) + if (ballId == gBagPockets[BALLS_POCKET].itemSlots[i-1].itemId) { - ballNext = gBagPockets[BALLS_POCKET].itemSlots[i+1].itemId; + ballNext = gBagPockets[BALLS_POCKET].itemSlots[i].itemId; break; } } @@ -1279,12 +1279,12 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler) bool32 bgmRestored = FALSE; bool32 battlerAnimsDone = FALSE; - // Start shiny animation if applicable for 1st pokemon + // Start shiny animation if applicable for 1st Pokémon if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); - // Start shiny animation if applicable for 2nd pokemon + // Start shiny animation if applicable for 2nd Pokémon if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive) TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]); @@ -1730,7 +1730,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) { u8 *txtPtr; u8 type; - u32 itemId; + u32 speciesId; struct Pokemon *mon; struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); @@ -1742,10 +1742,12 @@ static void MoveSelectionDisplayMoveType(u32 battler) if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_IVY_CUDGEL) { mon = &GetSideParty(GetBattlerSide(battler))[gBattlerPartyIndexes[battler]]; - itemId = GetMonData(mon, MON_DATA_HELD_ITEM); + speciesId = GetMonData(mon, MON_DATA_SPECIES); - if (ItemId_GetHoldEffect(itemId) == HOLD_EFFECT_MASK) - type = ItemId_GetSecondaryId(itemId); + if (speciesId == SPECIES_OGERPON_WELLSPRING_MASK || speciesId == SPECIES_OGERPON_WELLSPRING_MASK_TERA + || speciesId == SPECIES_OGERPON_HEARTHFLAME_MASK || speciesId == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA + || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK_TERA) + type = gBattleMons[battler].type2; else type = gBattleMoves[MOVE_IVY_CUDGEL].type; } diff --git a/src/battle_dome.c b/src/battle_dome.c index d098d1cae7cd..4819f6367d34 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -2224,7 +2224,7 @@ static void CreateDomeOpponentMon(u8 monPartyId, u16 tournamentTrainerId, u8 tou #ifdef BUGFIX u8 fixedIv = GetDomeTrainerMonIvs(DOME_TRAINERS[tournamentTrainerId].trainerId); #else - u8 fixedIv = GetDomeTrainerMonIvs(tournamentTrainerId); // BUG: Using the wrong ID. As a result, all Pokemon have ivs of 3. + u8 fixedIv = GetDomeTrainerMonIvs(tournamentTrainerId); // BUG: Using the wrong ID. As a result, all Pokémon have ivs of 3. #endif u8 level = SetFacilityPtrsGetLevel(); CreateMonWithEVSpreadNatureOTID(&gEnemyParty[monPartyId], @@ -2286,13 +2286,13 @@ static void CreateDomeOpponentMons(u16 tournamentTrainerId) } } -// Returns a bitmask representing which 2 of the trainer's 3 pokemon to select. +// Returns a bitmask representing which 2 of the trainer's 3 Pokémon to select. // The choice is calculated solely depending on the type effectiveness of their -// movesets against the player's pokemon. +// movesets against the player's Pokémon. // There is a 50% chance of either a "good" or "bad" selection mode being used. // In the good mode movesets are preferred which are more effective against the -// player, and in the bad mode the opposite is true. If all 3 pokemon tie, the -// other mode will be tried. If they tie again, the pokemon selection is random. +// player, and in the bad mode the opposite is true. If all 3 Pokémon tie, the +// other mode will be tried. If they tie again, the Pokémon selection is random. int GetDomeTrainerSelectedMons(u16 tournamentTrainerId) { int selectedMonBits; @@ -3928,12 +3928,12 @@ static u8 Task_GetInfoCardInput(u8 taskId) #undef tUsingAlternateSlot -static bool32 IsDomeHealingMoveEffect(u32 effect) +static bool32 IsDomeHealingMove(u32 move) { - if (IsHealingMoveEffect(effect)) + if (IsHealingMove(move)) return TRUE; // Check extra effects not considered plain healing by AI - switch(effect) + switch (gBattleMoves[move].effect) { case EFFECT_INGRAIN: case EFFECT_REFRESH: @@ -4360,7 +4360,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) allocatedArray[k] = IsDomeRareMove(move) ? 1 : 0; break; case MOVE_POINTS_HEAL: - allocatedArray[k] = IsDomeHealingMoveEffect(gBattleMoves[move].effect) ? 1 : 0; + allocatedArray[k] = IsDomeHealingMove(move) ? 1 : 0; break; case MOVE_POINTS_RISKY: allocatedArray[k] = IsDomeRiskyMoveEffect(gBattleMoves[move].effect) ? 1 : 0; @@ -4747,7 +4747,7 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) if (lost[1]) gSprites[sInfoCard->spriteIds[1 + arrId]].oam.paletteNum = 3; - // Draw left trainer's pokemon icons. + // Draw left trainer's Pokémon icons. for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { if (trainerIds[0] == TRAINER_PLAYER) @@ -4787,7 +4787,7 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) } } - // Draw right trainer's pokemon icons. + // Draw right trainer's Pokémon icons. for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { if (trainerIds[1] == TRAINER_PLAYER) @@ -5138,7 +5138,7 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun int movePower = 0; SetFacilityPtrsGetLevel(); - // Calc move points of all 4 moves for all 3 pokemon hitting all 3 target mons. + // Calc move points of all 4 moves for all 3 Pokémon hitting all 3 target mons. for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { for (j = 0; j < MAX_MON_MOVES; j++) diff --git a/src/battle_factory.c b/src/battle_factory.c index 4543bfbad46e..8e3f84b359d7 100644 --- a/src/battle_factory.c +++ b/src/battle_factory.c @@ -337,7 +337,7 @@ static void GenerateOpponentMons(void) if (gFacilityTrainerMons[monId].species == SPECIES_UNOWN) continue; - // Ensure none of the opponent's pokemon are the same as the potential rental pokemon for the player + // Ensure none of the opponent's Pokémon are the same as the potential rental Pokémon for the player for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock2Ptr->frontier.rentalMons); j++) { if (gFacilityTrainerMons[monId].species == gFacilityTrainerMons[gSaveBlock2Ptr->frontier.rentalMons[j].monId].species) @@ -346,7 +346,7 @@ static void GenerateOpponentMons(void) if (j != (int)ARRAY_COUNT(gSaveBlock2Ptr->frontier.rentalMons)) continue; - // "High tier" pokemon are only allowed on open level mode + // "High tier" Pokémon are only allowed on open level mode if (lvlMode == FRONTIER_LVL_50 && monId > FRONTIER_MONS_HIGH_TIER) continue; @@ -554,7 +554,7 @@ static void GenerateInitialRentalMons(void) i = 0; while (i != PARTY_SIZE) { - if (i < rentalRank) // The more times the player has rented, the more initial rentals are generated from a better set of pokemon + if (i < rentalRank) // The more times the player has rented, the more initial rentals are generated from a better set of Pokémon monId = GetFactoryMonId(factoryLvlMode, challengeNum, TRUE); else monId = GetFactoryMonId(factoryLvlMode, challengeNum, FALSE); @@ -562,7 +562,7 @@ static void GenerateInitialRentalMons(void) if (gFacilityTrainerMons[monId].species == SPECIES_UNOWN) continue; - // Cannot have two pokemon of the same species. + // Cannot have two Pokémon of the same species. for (j = firstMonId; j < firstMonId + i; j++) { u16 existingMonId = monIds[j]; diff --git a/src/battle_factory_screen.c b/src/battle_factory_screen.c index d010ec53c83b..e945361f338b 100644 --- a/src/battle_factory_screen.c +++ b/src/battle_factory_screen.c @@ -32,15 +32,15 @@ #include "constants/songs.h" #include "constants/rgb.h" -// Select_ refers to the first Pokemon selection screen where you choose your initial 3 rental Pokemon. -// Swap_ refers to the subsequent selection screens where you can swap a Pokemon with one from the beaten trainer +// Select_ refers to the first Pokémon selection screen where you choose your initial 3 rental Pokémon. +// Swap_ refers to the subsequent selection screens where you can swap a Pokémon with one from the beaten trainer // Note that, generally, "Action" will refer to the immediate actions that can be taken on each screen, -// i.e. selecting a pokemon or selecting the Cancel button +// i.e. selecting a Pokémon or selecting the Cancel button // The "Options menu" will refer to the popup menu that shows when some actions have been selected -#define SWAP_PLAYER_SCREEN 0 // The screen where the player selects which of their pokemon to swap away -#define SWAP_ENEMY_SCREEN 1 // The screen where the player selects which new pokemon from the defeated party to swap for +#define SWAP_PLAYER_SCREEN 0 // The screen where the player selects which of their Pokémon to swap away +#define SWAP_ENEMY_SCREEN 1 // The screen where the player selects which new Pokémon from the defeated party to swap for #define SELECTABLE_MONS_COUNT 6 @@ -89,7 +89,7 @@ struct FactorySelectableMon { u16 monId; u16 ballSpriteId; - u8 selectedId; // 0 - not selected, 1 - first pokemon, 2 - second pokemon, 3 - third pokemon + u8 selectedId; // 0 - not selected, 1 - first Pokémon, 2 - second Pokémon, 3 - third Pokémon struct Pokemon monData; }; @@ -1060,7 +1060,7 @@ static void SpriteCB_Pokeball(struct Sprite *sprite) { if (sprite->oam.paletteNum == IndexOfSpritePaletteTag(PALTAG_BALL_SELECTED)) { - // Pokeball selected, do rocking animation + // Poké Ball selected, do rocking animation if (sprite->animEnded) { if (sprite->data[0] != 0) @@ -1084,7 +1084,7 @@ static void SpriteCB_Pokeball(struct Sprite *sprite) } else { - // Pokeball not selected, remain still + // Poké Ball not selected, remain still StartSpriteAnimIfDifferent(sprite, 0); } } @@ -1521,7 +1521,7 @@ static void Select_Task_Exit(u8 taskId) } } -// Handles the Yes/No prompt when confirming the 3 selected rental pokemon +// Handles the Yes/No prompt when confirming the 3 selected rental Pokémon static void Select_Task_HandleYesNo(u8 taskId) { if (sFactorySelectScreen->monPicAnimating == TRUE) @@ -1543,14 +1543,14 @@ static void Select_Task_HandleYesNo(u8 taskId) PlaySE(SE_SELECT); if (sFactorySelectScreen->yesNoCursorPos == 0) { - // Selected Yes, confirmed selected pokemon + // Selected Yes, confirmed selected Pokémon Select_HideChosenMons(); gTasks[taskId].tState = 0; gTasks[taskId].func = Select_Task_Exit; } else { - // Selected No, continue choosing pokemon + // Selected No, continue choosing Pokémon Select_ErasePopupMenu(SELECT_WIN_YES_NO); Select_DeclineChosenMons(); sFactorySelectScreen->fadeSpeciesNameActive = TRUE; @@ -1560,7 +1560,7 @@ static void Select_Task_HandleYesNo(u8 taskId) } else if (JOY_NEW(B_BUTTON)) { - // Pressed B, Continue choosing pokemon + // Pressed B, Continue choosing Pokémon PlaySE(SE_SELECT); Select_ErasePopupMenu(SELECT_WIN_YES_NO); Select_DeclineChosenMons(); @@ -1582,7 +1582,7 @@ static void Select_Task_HandleYesNo(u8 taskId) } } -// Handles the popup menu that shows when a pokemon is selected +// Handles the popup menu that shows when a Pokémon is selected static void Select_Task_HandleMenu(u8 taskId) { switch (gTasks[taskId].tState) @@ -2416,7 +2416,7 @@ static void Swap_Task_Exit(u8 taskId) { case 0: // Set return value for script - // TRUE if player kept their current pokemon + // TRUE if player kept their current Pokémon if (sFactorySwapScreen->monSwapped == TRUE) { gTasks[taskId].tState++; @@ -2631,7 +2631,7 @@ static void Swap_Task_HandleMenu(u8 taskId) } } -// Handles input on the two main swap screens (choosing a current pokeon to get rid of, and choosing a new pokemon to receive) +// Handles input on the two main swap screens (choosing a current pokeon to get rid of, and choosing a new Pokémon to receive) static void Swap_Task_HandleChooseMons(u8 taskId) { switch (gTasks[taskId].tState) @@ -2646,7 +2646,7 @@ static void Swap_Task_HandleChooseMons(u8 taskId) case STATE_CHOOSE_MONS_HANDLE_INPUT: if (JOY_NEW(A_BUTTON)) { - // Run whatever action is currently selected (a pokeball, the Cancel button, etc.) + // Run whatever action is currently selected (a Poké Ball, the Cancel button, etc.) PlaySE(SE_SELECT); sFactorySwapScreen->fadeSpeciesNameActive = FALSE; Swap_PrintMonSpeciesAtFade(); @@ -3554,7 +3554,7 @@ static void Swap_HandleActionCursorChange(u8 cursorId) { if (cursorId < FRONTIER_PARTY_SIZE) { - // Cursor is on one of the pokemon + // Cursor is on one of the Pokémon gSprites[sFactorySwapScreen->cursorSpriteId].invisible = FALSE; Swap_HideActionButtonHighlights(); gSprites[sFactorySwapScreen->cursorSpriteId].x = gSprites[sFactorySwapScreen->ballSpriteIds[cursorId]].x; diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 06deedaaa544..2f72197bf982 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -103,7 +103,7 @@ void FreeBattleSpritesData(void) FREE_AND_SET_NULL(gBattleSpritesDataPtr); } -// Pokemon chooses move to use in Battle Palace rather than player +// Pokémon chooses move to use in Battle Palace rather than player u16 ChooseMoveAndTargetInBattlePalace(u32 battler) { s32 i, var1, var2; @@ -163,7 +163,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) chosenMoveId = BattleAI_ChooseMoveOrAction(); } - // If no moves matched the selected group, pick a new move from groups the pokemon has + // If no moves matched the selected group, pick a new move from groups the Pokémon has // In this case the AI is not checked again, so the choice may be worse // If a move is chosen this way, there's a 50% chance that it will be unable to use it anyway if (chosenMoveId == -1 || chosenMoveId >= MAX_MON_MOVES) @@ -356,7 +356,7 @@ static u16 GetBattlePalaceTarget(u32 battler) return BATTLE_OPPOSITE(battler) << 8; } -// Wait for the pokemon to finish appearing out from the pokeball on send out +// Wait for the Pokémon to finish appearing out from the Poké Ball on send out void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite) { u8 spriteId = sprite->data[1]; diff --git a/src/battle_main.c b/src/battle_main.c index 944a38686191..951766adcdc6 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3263,6 +3263,7 @@ const u8* FaintClearSetData(u32 battler) gProtectStructs[battler].quash = FALSE; gProtectStructs[battler].obstructed = FALSE; gProtectStructs[battler].silkTrapped = FALSE; + gProtectStructs[battler].burningBulwarked = FALSE; gProtectStructs[battler].endured = FALSE; gProtectStructs[battler].noValidMoves = FALSE; gProtectStructs[battler].helpingHand = FALSE; @@ -4727,7 +4728,7 @@ s8 GetMovePriority(u32 battler, u16 move) { priority++; } - else if (ability == ABILITY_TRIAGE && IsHealingMoveEffect(gBattleMoves[move].effect)) + else if (ability == ABILITY_TRIAGE && IsHealingMove(move)) priority += 3; if (gProtectStructs[battler].quash) @@ -5667,6 +5668,13 @@ void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk) { gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].type2 | F_DYNAMIC_TYPE_SET; } + else if (gBattleMoves[move].effect == EFFECT_IVY_CUDGEL + && (gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK_TERA + || gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA + || gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA )) + { + gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].type2 | F_DYNAMIC_TYPE_SET; + } else if (gBattleMoves[move].effect == EFFECT_NATURAL_GIFT) { if (ItemId_GetPocket(gBattleMons[battlerAtk].item) == POCKET_BERRIES) diff --git a/src/battle_message.c b/src/battle_message.c index 7d2c60d67a10..b421836f4a4b 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -304,7 +304,7 @@ static const u8 sText_PkmnsXPreventsYLoss[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} static const u8 sText_PkmnsXInfatuatedY[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\ninfatuated {B_ATK_NAME_WITH_PREFIX}!"); static const u8 sText_PkmnsXMadeYIneffective[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} ineffective!"); static const u8 sText_PkmnsXCuredYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!"); -static const u8 sText_ItSuckedLiquidOoze[] = _("It sucked up the\nLIQUID OOZE!"); +static const u8 sText_ItSuckedLiquidOoze[] = _("It sucked up the\nliquid ooze!"); static const u8 sText_PkmnTransformed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!"); static const u8 sText_PkmnsXTookAttack[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\ntook the attack!"); const u8 gText_PkmnsXPreventsSwitching[] = _("{B_BUFF1}'s {B_LAST_ABILITY}\nprevents switching!\p"); @@ -834,9 +834,11 @@ static const u8 sText_TheSeaOfFireDisappeared[] = _("The sea of fire around {B_A static const u8 sText_SwampEnvelopedSide[] = _("A swamp enveloped\n{B_DEF_TEAM2} team!"); static const u8 sText_TheSwampDisappeared[] = _("The swamp around {B_ATK_TEAM2}\nteam disappeared!"); static const u8 sText_HospitalityRestoration[] = _("The {B_ATK_PARTNER_NAME} drank down all\nthe matcha that Sinistcha made!"); +static const u8 sText_ElectroShockCharging[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nelectricity!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_ELECTROSHOCKCHARGING - BATTLESTRINGS_TABLE_START] = sText_ElectroShockCharging, [STRINGID_HOSPITALITYRESTORATION - BATTLESTRINGS_TABLE_START] = sText_HospitalityRestoration, [STRINGID_THESWAMPDISAPPEARED - BATTLESTRINGS_TABLE_START] = sText_TheSwampDisappeared, [STRINGID_SWAMPENVELOPEDSIDE - BATTLESTRINGS_TABLE_START] = sText_SwampEnvelopedSide, @@ -1764,6 +1766,7 @@ const u16 gFirstTurnOfTwoStringIds[] = [B_MSG_TURN1_FREEZE_SHOCK] = STRINGID_CLOAKEDINAFREEZINGLIGHT, [B_MSG_TURN1_SKY_DROP] = STRINGID_PKMNTOOKTARGETHIGH, [B_MSG_TURN1_METEOR_BEAM] = STRINGID_METEORBEAMCHARGING, + [B_MSG_TURN1_ELECTRO_SHOCK] = STRINGID_ELECTROSHOCKCHARGING, }; // Index copied from move's index in sTrappingMoves @@ -2921,7 +2924,7 @@ void BufferStringBattle(u16 stringID, u32 battler) } } break; - case STRINGID_USEDMOVE: // pokemon used a move msg + case STRINGID_USEDMOVE: // Pokémon used a move msg if (gBattleStruct->zmove.active && gBattleStruct->zmove.activeCategory != BATTLE_CATEGORY_STATUS) StringCopy(gBattleTextBuff3, GetZMoveName(gBattleMsgDataPtr->currentMove)); else if (IsMaxMove(gBattleMsgDataPtr->currentMove)) @@ -3236,7 +3239,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) { u32 dstID = 0; // if they used dstID, why not use srcID as well? const u8 *toCpy = NULL; - // This buffer may hold either the name of a trainer, pokemon, or item. + // This buffer may hold either the name of a trainer, Pokémon, or item. u8 text[max(max(max(32, TRAINER_NAME_LENGTH + 1), POKEMON_NAME_LENGTH + 1), ITEM_NAME_LENGTH)]; u8 multiplayerId; diff --git a/src/battle_pike.c b/src/battle_pike.c index 4a2065be4487..3869531d2090 100644 --- a/src/battle_pike.c +++ b/src/battle_pike.c @@ -1268,7 +1268,7 @@ static void TryHealMons(u8 healCount) for (i = 0; i < FRONTIER_PARTY_SIZE; i++) indices[i] = i; - // Only 'healCount' number of pokemon will be healed. + // Only 'healCount' number of Pokémon will be healed. // The order in which they're (attempted to be) healed is random, Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0])); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 91fcfd4aee88..ab9a544c3465 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3134,6 +3134,9 @@ void SetMoveEffect(bool32 primary, u32 certain) switch (gBattleScripting.moveEffect) { case MOVE_EFFECT_CONFUSION: + if (gCurrentMove == MOVE_ALLURING_VOICE && !gProtectStructs[gEffectBattler].statRaised) + break; + if (!CanBeConfused(gEffectBattler)) { gBattlescriptCurrInstr++; @@ -3523,6 +3526,7 @@ void SetMoveEffect(bool32 primary, u32 certain) gProtectStructs[gBattlerTarget].banefulBunkered = FALSE; gProtectStructs[gBattlerTarget].obstructed = FALSE; gProtectStructs[gBattlerTarget].silkTrapped = FALSE; + gProtectStructs[gBattlerAttacker].burningBulwarked = FALSE; BattleScriptPush(gBattlescriptCurrInstr + 1); if (gCurrentMove == MOVE_HYPERSPACE_FURY) gBattlescriptCurrInstr = BattleScript_HyperspaceFuryRemoveProtect; @@ -4242,7 +4246,7 @@ static void Cmd_getexp(void) if (IsTradedMon(&gPlayerParty[*expMonId])) { - // check if the pokemon doesn't belong to the player + // check if the Pokémon doesn't belong to the player if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && *expMonId >= 3) i = STRINGID_EMPTYSTRING4; else @@ -5322,6 +5326,15 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_KingsShieldEffect; effect = 1; } + else if (gProtectStructs[gBattlerTarget].burningBulwarked) + { + gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE; + gBattleScripting.moveEffect = MOVE_EFFECT_BURN | MOVE_EFFECT_AFFECTS_USER; + PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_BURNING_BULWARK); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BanefulBunkerEffect; + effect = 1; + } // Not strictly a protect effect, but works the same way else if (gProtectStructs[gBattlerTarget].beakBlastCharge && CanBeBurned(gBattlerAttacker) @@ -5746,7 +5759,7 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; - case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokemon. + case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokémon. { u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); // Set a flag if move hits either target (for throat spray that can't check damage) @@ -6115,6 +6128,7 @@ static void Cmd_moveend(void) gBattleStruct->zmove.effect = EFFECT_HIT; gBattleStruct->hitSwitchTargetFailed = FALSE; gBattleStruct->isAtkCancelerForCalledMove = FALSE; + gBattleStruct->swapDamageCategory = FALSE; gBattleStruct->enduredDamage = 0; gBattleScripting.moveendState++; break; @@ -9196,28 +9210,14 @@ static void Cmd_various(void) i = GetBattlerAbility(gBattlerAbility); if (IsBattlerAlive(gBattlerAbility) && (i == ABILITY_RECEIVER || i == ABILITY_POWER_OF_ALCHEMY) - && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD) - { - switch (gBattleMons[battler].ability) - { // Can't copy these abilities. - case ABILITY_POWER_OF_ALCHEMY: case ABILITY_RECEIVER: - case ABILITY_FORECAST: case ABILITY_MULTITYPE: - case ABILITY_FLOWER_GIFT: case ABILITY_ILLUSION: - case ABILITY_WONDER_GUARD: case ABILITY_ZEN_MODE: - case ABILITY_STANCE_CHANGE: case ABILITY_IMPOSTER: - case ABILITY_POWER_CONSTRUCT: case ABILITY_BATTLE_BOND: - case ABILITY_SCHOOLING: case ABILITY_COMATOSE: - case ABILITY_SHIELDS_DOWN: case ABILITY_DISGUISE: - case ABILITY_RKS_SYSTEM: case ABILITY_TRACE: - case ABILITY_ZERO_TO_HERO: - break; - default: - gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[battler].ability; // re-using the variable for trace - gBattleScripting.battler = battler; - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_ReceiverActivates; - return; - } + && GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD + && !gAbilities[gBattleMons[battler].ability].cantBeCopied) + { + gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[battler].ability; // re-using the variable for trace + gBattleScripting.battler = battler; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = BattleScript_ReceiverActivates; + return; } break; } @@ -9315,7 +9315,7 @@ static void Cmd_various(void) case VARIOUS_SET_SIMPLE_BEAM: { VARIOUS_ARGS(const u8 *failInstr); - if (IsSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); @@ -9339,8 +9339,8 @@ static void Cmd_various(void) case VARIOUS_TRY_ENTRAINMENT: { VARIOUS_ARGS(const u8 *failInstr); - if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) - || IsEntrainmentBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeCopied + || gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = cmd->failInstr; @@ -10250,12 +10250,6 @@ static void Cmd_various(void) gBattlescriptCurrInstr = cmd->nextInstr; return; } - case VARIOUS_PHOTON_GEYSER_CHECK: - { - VARIOUS_ARGS(); - gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(battler) == BATTLE_CATEGORY_SPECIAL); - break; - } case VARIOUS_SHELL_SIDE_ARM_CHECK: // 0% chance GameFreak actually checks this way according to DaWobblefet, but this is the only functional explanation at the moment { VARIOUS_ARGS(); @@ -10725,6 +10719,11 @@ static void Cmd_setprotectlike(void) gProtectStructs[gBattlerAttacker].silkTrapped = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECTED_ITSELF; } + else if (gCurrentMove == MOVE_BURNING_BULWARK) + { + gProtectStructs[gBattlerAttacker].burningBulwarked = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECTED_ITSELF; + } gDisableStructs[gBattlerAttacker].protectUses++; fail = FALSE; @@ -11807,7 +11806,7 @@ static void Cmd_forcerandomswitch(void) { firstMonId = 0; lastMonId = PARTY_SIZE; - battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one Pokémon out in single battles battler1PartyId = gBattlerPartyIndexes[gBattlerTarget]; } @@ -12357,7 +12356,7 @@ static void Cmd_setsubstitute(void) } else { - gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; // one bit value will only work for pokemon which max hp can go to 1020(which is more than possible in games) + gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; // one bit value will only work for Pokémon which max hp can go to 1020(which is more than possible in games) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -13853,7 +13852,7 @@ static void Cmd_tryswapitems(void) { gBattlescriptCurrInstr = cmd->failInstr; } - // can't swap if two pokemon don't have an item + // can't swap if two Pokémon don't have an item // or if either of them is an enigma berry or a mail else if ((gBattleMons[gBattlerAttacker].item == ITEM_NONE && gBattleMons[gBattlerTarget].item == ITEM_NONE) || !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item) @@ -13938,9 +13937,9 @@ static void Cmd_trycopyability(void) if (gBattleMons[battler].ability == defAbility || defAbility == ABILITY_NONE - || IsRolePlayDoodleBannedAbilityAttacker(gBattleMons[battler].ability) - || IsRolePlayDoodleBannedAbilityAttacker(gBattleMons[BATTLE_PARTNER(battler)].ability) - || IsRolePlayDoodleBannedAbility(defAbility)) + || gAbilities[gBattleMons[battler].ability].cantBeSuppressed + || gAbilities[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed + || gAbilities[defAbility].cantBeCopied) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -14016,7 +14015,7 @@ static void Cmd_setgastroacid(void) { CMD_ARGS(const u8 *failInstr); - if (IsGastroAcidBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSuppressed) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -14116,8 +14115,8 @@ static void Cmd_tryswapabilities(void) { CMD_ARGS(const u8 *failInstr); - if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) - || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeSwapped + || gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSwapped) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = cmd->failInstr; @@ -15476,7 +15475,8 @@ static void Cmd_tryworryseed(void) { CMD_ARGS(const u8 *failInstr); - if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) + if (gAbilities[gBattleMons[gBattlerTarget].ability].cantBeOverwritten + || gBattleMons[gBattlerTarget].ability == ABILITY_INSOMNIA) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); @@ -16575,3 +16575,10 @@ void BS_AllySwitchFailChance(void) } gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_SetPhotonGeyserCategory(void) +{ + NATIVE_ARGS(); + gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) == BATTLE_CATEGORY_PHYSICAL); + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_setup.c b/src/battle_setup.c index 750191d74ff8..15a91112b9ab 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -111,7 +111,7 @@ EWRAM_DATA static u8 *sTrainerBBattleScriptRetAddr = NULL; EWRAM_DATA static bool8 sShouldCheckTrainerBScript = FALSE; EWRAM_DATA static u8 sNoOfPossibleTrainerRetScripts = 0; -// The first transition is used if the enemy pokemon are lower level than our pokemon. +// The first transition is used if the enemy Pokémon are lower level than our Pokémon. // Otherwise, the second transition is used. static const u8 sBattleTransitionTable_Wild[][2] = { @@ -908,7 +908,7 @@ u8 GetTrainerBattleTransition(void) return B_TRANSITION_AQUA; if (gTrainers[gTrainerBattleOpponent_A].doubleBattle == TRUE) - minPartyCount = 2; // double battles always at least have 2 pokemon. + minPartyCount = 2; // double battles always at least have 2 Pokémon. else minPartyCount = 1; diff --git a/src/battle_tent.c b/src/battle_tent.c index b7a9daecba4c..c003affebe9f 100644 --- a/src/battle_tent.c +++ b/src/battle_tent.c @@ -309,7 +309,7 @@ static void GenerateInitialRentalMons(void) i = 0; while (i != PARTY_SIZE) { - // Cannot have two pokemon of the same species. + // Cannot have two Pokémon of the same species. monSetId = Random() % NUM_SLATEPORT_TENT_MONS; for (j = firstMonId; j < firstMonId + i; j++) { @@ -390,7 +390,7 @@ static void GenerateOpponentMons(void) { sRandMonId = monSet[Random() % numMons]; - // Ensure none of the opponent's pokemon are the same as the potential rental pokemon for the player + // Ensure none of the opponent's Pokémon are the same as the potential rental Pokémon for the player for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock2Ptr->frontier.rentalMons); j++) { if (gFacilityTrainerMons[sRandMonId].species == gFacilityTrainerMons[gSaveBlock2Ptr->frontier.rentalMons[j].monId].species) diff --git a/src/battle_tower.c b/src/battle_tower.c index 53ed39f2368c..bc0970e7b0ee 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -1646,8 +1646,8 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) } // Regular battle frontier trainer. - // Attempt to fill the trainer's party with random Pokemon until 3 have been - // successfully chosen. The trainer's party may not have duplicate pokemon species + // Attempt to fill the trainer's party with random Pokémon until 3 have been + // successfully chosen. The trainer's party may not have duplicate Pokémon species // or duplicate held items. for (bfMonCount = 0; monSet[bfMonCount] != 0xFFFF; bfMonCount++) ; @@ -1657,12 +1657,12 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) { u16 monId = monSet[Random() % bfMonCount]; - // "High tier" pokemon are only allowed on open level mode + // "High tier" Pokémon are only allowed on open level mode // 20 is not a possible value for level here if ((level == FRONTIER_MAX_LEVEL_50 || level == 20) && monId > FRONTIER_MONS_HIGH_TIER) continue; - // Ensure this pokemon species isn't a duplicate. + // Ensure this Pokémon species isn't a duplicate. for (j = 0; j < i + firstMonId; j++) { if (GetMonData(&gEnemyParty[j], MON_DATA_SPECIES, NULL) == gFacilityTrainerMons[monId].species) @@ -1681,7 +1681,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) if (j != i + firstMonId) continue; - // Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary + // Ensure this exact Pokémon index isn't a duplicate. This check doesn't seem necessary // because the species and held items were already checked directly above. for (j = 0; j < i; j++) { @@ -1693,7 +1693,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) chosenMonIndices[i] = monId; - // Place the chosen pokemon into the trainer's party. + // Place the chosen Pokémon into the trainer's party. CreateMonWithEVSpreadNatureOTID(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monId].species, level, @@ -1703,7 +1703,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) otID); friendship = MAX_FRIENDSHIP; - // Give the chosen pokemon its specified moves. + // Give the chosen Pokémon its specified moves. for (j = 0; j < MAX_MON_MOVES; j++) { SetMonMoveSlot(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monId].moves[j], j); @@ -1714,7 +1714,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_FRIENDSHIP, &friendship); SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]); - // The pokemon was successfully added to the trainer's party, so it's safe to move on to + // The Pokémon was successfully added to the trainer's party, so it's safe to move on to // the next party slot. i++; } @@ -1770,7 +1770,7 @@ u16 GetRandomFrontierMonFromSet(u16 trainerId) do { - // "High tier" pokemon are only allowed on open level mode + // "High tier" Pokémon are only allowed on open level mode // 20 is not a possible value for level here monId = monSet[Random() % numMons]; } while((level == FRONTIER_MAX_LEVEL_50 || level == 20) && monId > FRONTIER_MONS_HIGH_TIER); @@ -2443,8 +2443,8 @@ static void GetPotentialPartnerMoveAndSpecies(u16 trainerId, u16 monId) // These partners can be an NPC or a former/record-mixed Apprentice // When talked to, their response consists of: // PARTNER_MSGID_INTRO - A greeting -// PARTNER_MSGID_MON1 - Naming one pokemon on their team, and a move it has -// PARTNER_MSGID_MON2_ASK - Naming a second pokemon on their team, a move it has, and asking if they'd like to be their partner +// PARTNER_MSGID_MON1 - Naming one Pokémon on their team, and a move it has +// PARTNER_MSGID_MON2_ASK - Naming a second Pokémon on their team, a move it has, and asking if they'd like to be their partner // PARTNER_MSGID_ACCEPT - If the player agrees to be their partner // PARTNER_MSGID_REJECT - If the player declines to be their partner static void ShowPartnerCandidateMessage(void) @@ -2762,7 +2762,7 @@ static void AwardBattleTowerRibbons(void) #ifdef BUGFIX struct RibbonCounter ribbons[MAX_FRONTIER_PARTY_SIZE]; #else - struct RibbonCounter ribbons[3]; // BUG: 4 Pokemon can receive ribbons in a double battle mode. + struct RibbonCounter ribbons[3]; // BUG: 4 Pokémon can receive ribbons in a double battle mode. #endif u8 ribbonType = 0; u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; @@ -3458,7 +3458,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) { u16 monId = monSet[Random() % bfMonCount]; - // Ensure this pokemon species isn't a duplicate. + // Ensure this Pokémon species isn't a duplicate. for (j = 0; j < i + firstMonId; j++) { if (GetMonData(&gEnemyParty[j], MON_DATA_SPECIES, NULL) == gFacilityTrainerMons[monId].species) @@ -3477,7 +3477,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) if (j != i + firstMonId) continue; - // Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary + // Ensure this exact Pokémon index isn't a duplicate. This check doesn't seem necessary // because the species and held items were already checked directly above. for (j = 0; j < i; j++) { @@ -3489,7 +3489,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) chosenMonIndices[i] = monId; - // Place the chosen pokemon into the trainer's party. + // Place the chosen Pokémon into the trainer's party. CreateMonWithEVSpreadNatureOTID(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monId].species, level, @@ -3499,7 +3499,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) otID); friendship = MAX_FRIENDSHIP; - // Give the chosen pokemon its specified moves. + // Give the chosen Pokémon its specified moves. for (j = 0; j < MAX_MON_MOVES; j++) { SetMonMoveSlot(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monId].moves[j], j); @@ -3510,7 +3510,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_FRIENDSHIP, &friendship); SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monId].itemTableId]); - // The pokemon was successfully added to the trainer's party, so it's safe to move on to + // The Pokémon was successfully added to the trainer's party, so it's safe to move on to // the next party slot. i++; } diff --git a/src/battle_tv.c b/src/battle_tv.c index 439c69908986..61edb4330a73 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -699,7 +699,7 @@ static const u16 *const sPointsArray[] = }; // Points will always be calculated for these messages -// even if current pokemon does not have corresponding move +// even if current Pokémon does not have corresponding move static const u16 sSpecialBattleStrings[] = { STRINGID_PKMNPERISHCOUNTFELL, STRINGID_PKMNWISHCAMETRUE, STRINGID_PKMNLOSTPPGRUDGE, diff --git a/src/battle_util.c b/src/battle_util.c index fa34fc7460a8..04ba26ed861c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -94,224 +94,6 @@ static const u8 sPkblToEscapeFactor[][3] = { static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1}; static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4}; -static const u16 sSkillSwapBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_WONDER_GUARD, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sRolePlayDoodleBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_FLOWER_GIFT, - ABILITY_FORECAST, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_IMPOSTER, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_POWER_OF_ALCHEMY, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RECEIVER, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRACE, - ABILITY_WONDER_GUARD, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sRolePlayDoodleBannedAttackerAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sWorrySeedBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_INSOMNIA, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sGastroAcidBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sEntrainmentBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sEntrainmentBannedAttackerAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_FLOWER_GIFT, - ABILITY_FORECAST, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_HUNGER_SWITCH, - ABILITY_ICE_FACE, - ABILITY_ILLUSION, - ABILITY_IMPOSTER, - ABILITY_MULTITYPE, - ABILITY_NEUTRALIZING_GAS, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_POWER_OF_ALCHEMY, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RECEIVER, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_TRACE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -static const u16 sSimpleBeamBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_BATTLE_BOND, - ABILITY_COMATOSE, - ABILITY_COMMANDER, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_HADRON_ENGINE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_ORICHALCUM_PULSE, - ABILITY_POWER_CONSTRUCT, - ABILITY_PROTOSYNTHESIS, - ABILITY_QUARK_DRIVE, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_SIMPLE, - ABILITY_STANCE_CHANGE, - ABILITY_TRUANT, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - static u8 CalcBeatUpPower(void) { u8 basePower; @@ -985,114 +767,6 @@ void HandleAction_ActionFinished(void) } } -static const u8 sAbilitiesAffectedByMoldBreaker[] = -{ - [ABILITY_BATTLE_ARMOR] = 1, - [ABILITY_CLEAR_BODY] = 1, - [ABILITY_DAMP] = 1, - [ABILITY_DRY_SKIN] = 1, - [ABILITY_FILTER] = 1, - [ABILITY_FLASH_FIRE] = 1, - [ABILITY_FLOWER_GIFT] = 1, - [ABILITY_HEATPROOF] = 1, - [ABILITY_HYPER_CUTTER] = 1, - [ABILITY_IMMUNITY] = 1, - [ABILITY_INNER_FOCUS] = 1, - [ABILITY_INSOMNIA] = 1, - [ABILITY_KEEN_EYE] = 1, - [ABILITY_LEAF_GUARD] = 1, - [ABILITY_LEVITATE] = 1, - [ABILITY_LIGHTNING_ROD] = 1, - [ABILITY_LIMBER] = 1, - [ABILITY_MAGMA_ARMOR] = 1, - [ABILITY_MARVEL_SCALE] = 1, - [ABILITY_MOTOR_DRIVE] = 1, - [ABILITY_OBLIVIOUS] = 1, - [ABILITY_OWN_TEMPO] = 1, - [ABILITY_SAND_VEIL] = 1, - [ABILITY_SHELL_ARMOR] = 1, - [ABILITY_SHIELD_DUST] = 1, - [ABILITY_SIMPLE] = 1, - [ABILITY_SNOW_CLOAK] = 1, - [ABILITY_SOLID_ROCK] = 1, - [ABILITY_SOUNDPROOF] = 1, - [ABILITY_STICKY_HOLD] = 1, - [ABILITY_STORM_DRAIN] = 1, - [ABILITY_STURDY] = 1, - [ABILITY_SUCTION_CUPS] = 1, - [ABILITY_TANGLED_FEET] = 1, - [ABILITY_THICK_FAT] = 1, - [ABILITY_UNAWARE] = 1, - [ABILITY_VITAL_SPIRIT] = 1, - [ABILITY_VOLT_ABSORB] = 1, - [ABILITY_WATER_ABSORB] = 1, - [ABILITY_WATER_VEIL] = 1, - [ABILITY_WHITE_SMOKE] = 1, - [ABILITY_WONDER_GUARD] = 1, - [ABILITY_BIG_PECKS] = 1, - [ABILITY_CONTRARY] = 1, - [ABILITY_FRIEND_GUARD] = 1, - [ABILITY_HEAVY_METAL] = 1, - [ABILITY_LIGHT_METAL] = 1, - [ABILITY_MAGIC_BOUNCE] = 1, - [ABILITY_MULTISCALE] = 1, - [ABILITY_SAP_SIPPER] = 1, - [ABILITY_TELEPATHY] = 1, - [ABILITY_WONDER_SKIN] = 1, - [ABILITY_AROMA_VEIL] = 1, - [ABILITY_BULLETPROOF] = 1, - [ABILITY_FLOWER_VEIL] = 1, - [ABILITY_FUR_COAT] = 1, - [ABILITY_OVERCOAT] = 1, - [ABILITY_SWEET_VEIL] = 1, - [ABILITY_DAZZLING] = 1, - [ABILITY_DISGUISE] = 1, - [ABILITY_FLUFFY] = 1, - [ABILITY_QUEENLY_MAJESTY] = 1, - [ABILITY_WATER_BUBBLE] = 1, - [ABILITY_MIRROR_ARMOR] = 1, - [ABILITY_PUNK_ROCK] = 1, - [ABILITY_ICE_SCALES] = 1, - [ABILITY_ICE_FACE] = 1, - [ABILITY_PASTEL_VEIL] = 1, - [ABILITY_ARMOR_TAIL] = 1, - [ABILITY_EARTH_EATER] = 1, - [ABILITY_GOOD_AS_GOLD] = 1, - [ABILITY_PURIFYING_SALT] = 1, - [ABILITY_WELL_BAKED_BODY] = 1, - [ABILITY_MINDS_EYE] = 1, - [ABILITY_ILLUMINATE] = 1, -}; - -static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] = -{ - [ABILITY_AS_ONE_ICE_RIDER] = 1, - [ABILITY_AS_ONE_SHADOW_RIDER] = 1, - [ABILITY_BATTLE_BOND] = 1, - [ABILITY_COMATOSE] = 1, - [ABILITY_DISGUISE] = 1, - [ABILITY_FLOWER_GIFT] = 1, - [ABILITY_FORECAST] = 1, - [ABILITY_GULP_MISSILE] = 1, - [ABILITY_HUNGER_SWITCH] = 1, - [ABILITY_ICE_FACE] = 1, - [ABILITY_ILLUSION] = 1, - [ABILITY_IMPOSTER] = 1, - [ABILITY_MULTITYPE] = 1, - [ABILITY_NEUTRALIZING_GAS] = 1, - [ABILITY_NONE] = 1, - [ABILITY_POWER_CONSTRUCT] = 1, - [ABILITY_POWER_OF_ALCHEMY] = 1, - [ABILITY_RECEIVER] = 1, - [ABILITY_RKS_SYSTEM] = 1, - [ABILITY_SCHOOLING] = 1, - [ABILITY_SHIELDS_DOWN] = 1, - [ABILITY_STANCE_CHANGE] = 1, - [ABILITY_TRACE] = 1, - [ABILITY_ZEN_MODE] = 1, - [ABILITY_ZERO_TO_HERO] = 1, -}; - static const u8 sHoldEffectToType[][2] = { {HOLD_EFFECT_BUG_POWER, TYPE_BUG}, @@ -2870,7 +2544,7 @@ u8 DoBattlerEndTurnEffects(void) { MAGIC_GUARD_CHECK; // R/S does not perform this sleep check, which causes the nightmare effect to - // persist even after the affected Pokemon has been awakened by Shed Skin. + // persist even after the affected Pokémon has been awakened by Shed Skin. if (gBattleMons[battler].status1 & STATUS1_SLEEP) { gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 4; @@ -2959,7 +2633,7 @@ u8 DoBattlerEndTurnEffects(void) } if (gBattlerAttacker != gBattlersCount) { - effect = 2; // a pokemon was awaken + effect = 2; // a Pokémon was awaken break; } else @@ -3023,7 +2697,7 @@ u8 DoBattlerEndTurnEffects(void) if (gDisableStructs[battler].disabledMove == gBattleMons[battler].moves[i]) break; } - if (i == MAX_MON_MOVES) // pokemon does not have the disabled move anymore + if (i == MAX_MON_MOVES) // Pokémon does not have the disabled move anymore { gDisableStructs[battler].disabledMove = 0; gDisableStructs[battler].disableTimer = 0; @@ -3040,7 +2714,7 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_ENCORE: // encore if (gDisableStructs[battler].encoreTimer != 0) { - if (gBattleMons[battler].moves[gDisableStructs[battler].encoredMovePos] != gDisableStructs[battler].encoredMove) // pokemon does not have the encored move anymore + if (gBattleMons[battler].moves[gDisableStructs[battler].encoredMovePos] != gDisableStructs[battler].encoredMove) // Pokémon does not have the encored move anymore { gDisableStructs[battler].encoredMove = 0; gDisableStructs[battler].encoreTimer = 0; @@ -3429,7 +3103,8 @@ bool32 HandleFaintedMonActions(void) && gCurrentTurnActionNumber != gBattlersCount) { gAbsentBattlerFlags |= gBitTable[gBattlerFainted]; - return FALSE; + if (gBattleStruct->faintedActionsState != 1) + return FALSE; } break; case 3: @@ -4368,7 +4043,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { // overworld weather started rain, so just do electric terrain anim gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); - gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; } @@ -4377,7 +4052,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) { gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain); effect++; } @@ -4792,6 +4467,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_SHIELDS_DOWN: if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_HP_PERCENT)) { + gBattlerAttacker = battler; BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3); effect++; } @@ -5117,6 +4793,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_POWER_CONSTRUCT: if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_HP_PERCENT)) { + gBattlerAttacker = battler; BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3); effect++; } @@ -5138,6 +4815,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_HUNGER_SWITCH: if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END)) { + gBattlerAttacker = battler; BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup); effect++; } @@ -5455,34 +5133,22 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED && IsMoveMakingContact(move, gBattlerAttacker) - && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget)) - { - switch (gBattleMons[gBattlerAttacker].ability) - { - case ABILITY_MUMMY: - case ABILITY_BATTLE_BOND: - case ABILITY_COMATOSE: - case ABILITY_DISGUISE: - case ABILITY_MULTITYPE: - case ABILITY_POWER_CONSTRUCT: - case ABILITY_RKS_SYSTEM: - case ABILITY_SCHOOLING: - case ABILITY_SHIELDS_DOWN: - case ABILITY_STANCE_CHANGE: - break; - default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); - break; - } - - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MummyActivates; - effect++; + && gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget) + && gBattleMons[gBattlerTarget].ability != ABILITY_MUMMY + && gBattleMons[gBattlerTarget].ability != ABILITY_LINGERING_AROMA + && !gAbilities[gBattleMons[gBattlerTarget].ability].cantBeSuppressed) + { + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } + + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MummyActivates; + effect++; + break; } break; case ABILITY_WANDERING_SPIRIT: @@ -5490,40 +5156,22 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker) && TARGET_TURN_DAMAGED && IsMoveMakingContact(move, gBattlerAttacker) - && !IsDynamaxed(gBattlerTarget)) - { - switch (gBattleMons[gBattlerAttacker].ability) - { - case ABILITY_DISGUISE: - case ABILITY_FLOWER_GIFT: - case ABILITY_GULP_MISSILE: - case ABILITY_HUNGER_SWITCH: - case ABILITY_ICE_FACE: - case ABILITY_ILLUSION: - case ABILITY_IMPOSTER: - case ABILITY_RECEIVER: - case ABILITY_RKS_SYSTEM: - case ABILITY_SCHOOLING: - case ABILITY_STANCE_CHANGE: - case ABILITY_WONDER_GUARD: - case ABILITY_ZEN_MODE: - case ABILITY_ZERO_TO_HERO: - break; - default: - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) - { - RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); - break; - } - - gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; - gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; - gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WanderingSpiritActivates; - effect++; + && !IsDynamaxed(gBattlerTarget) + && !gAbilities[gBattleMons[gBattlerAttacker].ability].cantBeSwapped) + { + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) + { + RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } + + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; + gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; + gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WanderingSpiritActivates; + effect++; + break; } break; case ABILITY_ANGER_POINT: @@ -6142,23 +5790,23 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (gBattleMons[i].ability == ABILITY_TRACE && (gBattleResources->flags->flags[i] & RESOURCE_FLAG_TRACED)) { u32 chosenTarget; - u32 side = (BATTLE_OPPOSITE(GetBattlerPosition(i))) & BIT_SIDE; // side of the opposing pokemon + u32 side = (BATTLE_OPPOSITE(GetBattlerPosition(i))) & BIT_SIDE; // side of the opposing Pokémon u32 target1 = GetBattlerAtPosition(side); u32 target2 = GetBattlerAtPosition(side + BIT_FLANK); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { - if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0 - && !sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) + if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0 + && !gAbilities[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0) chosenTarget = GetBattlerAtPosition((RandomPercentage(RNG_TRACE, 50) * 2) | side), effect++; - else if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0) + else if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0) chosenTarget = target1, effect++; - else if (!sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) + else if (!gAbilities[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0) chosenTarget = target2, effect++; } else { - if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0) + if (!gAbilities[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0) chosenTarget = target1, effect++; } @@ -6320,35 +5968,6 @@ bool32 TryPrimalReversion(u32 battler) return FALSE; } -static const u16 sNeutralizingGasBannedAbilities[] = -{ - ABILITY_AS_ONE_ICE_RIDER, - ABILITY_AS_ONE_SHADOW_RIDER, - ABILITY_COMATOSE, - ABILITY_DISGUISE, - ABILITY_GULP_MISSILE, - ABILITY_ICE_FACE, - ABILITY_MULTITYPE, - ABILITY_POWER_CONSTRUCT, - ABILITY_RKS_SYSTEM, - ABILITY_SCHOOLING, - ABILITY_SHIELDS_DOWN, - ABILITY_STANCE_CHANGE, - ABILITY_ZEN_MODE, - ABILITY_ZERO_TO_HERO, -}; - -bool32 IsNeutralizingGasBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sNeutralizingGasBannedAbilities); i++) - { - if (ability == sNeutralizingGasBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - bool32 IsNeutralizingGasOnField(void) { u32 i; @@ -6382,10 +6001,13 @@ bool32 IsMoldBreakerTypeAbility(u32 ability) u32 GetBattlerAbility(u32 battler) { + if (gAbilities[gBattleMons[battler].ability].cantBeSuppressed) + return gBattleMons[battler].ability; + if (gStatuses3[battler] & STATUS3_GASTRO_ACID) return ABILITY_NONE; - if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battler].ability)) + if (IsNeutralizingGasOnField() && gBattleMons[battler].ability != ABILITY_NEUTRALIZING_GAS) return ABILITY_NONE; if (IsMyceliumMightOnField()) @@ -6394,7 +6016,7 @@ u32 GetBattlerAbility(u32 battler) if (((IsMoldBreakerTypeAbility(gBattleMons[gBattlerAttacker].ability) && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) || gBattleMoves[gCurrentMove].ignoresTargetAbility) - && sAbilitiesAffectedByMoldBreaker[gBattleMons[battler].ability] + && gAbilities[gBattleMons[battler].ability].breakable && gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker && gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE && gCurrentTurnActionNumber < gBattlersCount) @@ -8492,6 +8114,8 @@ bool32 IsBattlerProtected(u32 battler, u32 move) return TRUE; else if (gProtectStructs[battler].banefulBunkered) return TRUE; + else if (gProtectStructs[battler].burningBulwarked) + return TRUE; else if ((gProtectStructs[battler].obstructed || gProtectStructs[battler].silkTrapped) && !IS_MOVE_STATUS(move)) return TRUE; else if (gProtectStructs[battler].spikyShielded) @@ -8998,6 +8622,10 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3 basePower += 50 * gBattleStruct->timesGotHit[GetBattlerSide(battlerAtk)][gBattlerPartyIndexes[battlerAtk]]; basePower = (basePower > 350) ? 350 : basePower; break; + case EFFECT_FICKLE_BEAM: + if (RandomPercentage(RNG_FICKLE_BEAM, 30)) + basePower *= 2; + break; } // Move-specific base power changes @@ -10943,95 +10571,6 @@ bool32 CanFling(u32 battler) return TRUE; } -// Ability checks -bool32 IsSkillSwapBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sSkillSwapBannedAbilities); i++) - { - if (ability == sSkillSwapBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsRolePlayDoodleBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sRolePlayDoodleBannedAbilities); i++) - { - if (ability == sRolePlayDoodleBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsRolePlayDoodleBannedAbilityAttacker(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sRolePlayDoodleBannedAttackerAbilities); i++) - { - if (ability == sRolePlayDoodleBannedAttackerAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsWorrySeedBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sWorrySeedBannedAbilities); i++) - { - if (ability == sWorrySeedBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsGastroAcidBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sGastroAcidBannedAbilities); i++) - { - if (ability == sGastroAcidBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsEntrainmentBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sEntrainmentBannedAbilities); i++) - { - if (ability == sEntrainmentBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsEntrainmentBannedAbilityAttacker(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sEntrainmentBannedAttackerAbilities); i++) - { - if (ability == sEntrainmentBannedAttackerAbilities[i]) - return TRUE; - } - return FALSE; -} - -bool32 IsSimpleBeamBannedAbility(u16 ability) -{ - u32 i; - for (i = 0; i < ARRAY_COUNT(sSimpleBeamBannedAbilities); i++) - { - if (ability == sSimpleBeamBannedAbilities[i]) - return TRUE; - } - return FALSE; -} - // Sort an array of battlers by speed // Useful for effects like pickpocket, eject button, red card, dancer void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast) diff --git a/src/birch_pc.c b/src/birch_pc.c index 1f0ab2349894..8256a1378bd5 100644 --- a/src/birch_pc.c +++ b/src/birch_pc.c @@ -20,7 +20,7 @@ bool16 ScriptGetPokedexInfo(void) return IsNationalPokedexEnabled(); } -// This shows your Hoenn Pokedex rating and not your National Dex. +// This shows your Hoenn Pokédex rating and not your National Dex. const u8 *GetPokedexRatingText(u16 count) { if (count < 10) diff --git a/src/contest.c b/src/contest.c index 6b7322335c45..e0c5969a0609 100644 --- a/src/contest.c +++ b/src/contest.c @@ -194,7 +194,7 @@ static void SwapMoveDescAndContestTilemaps(void); #define CONTESTANT_TEXT_COLOR_START 10 enum { -// The "{Pokemon Name} / {Trainer Name}" windows. +// The "{Pokémon Name} / {Trainer Name}" windows. WIN_CONTESTANT0_NAME, WIN_CONTESTANT1_NAME, WIN_CONTESTANT2_NAME, @@ -3429,11 +3429,11 @@ static void RankContestants(void) // For each contestant, find the best rank with their point total. // Normally, each point total is different, and this will output the - // rankings as expected. However, if two pokemon are tied, then they + // rankings as expected. However, if two Pokémon are tied, then they // both get the best rank for that point total. // // For example if the point totals are [100, 80, 80, 50], the ranks will - // be [1, 2, 2, 4]. The pokemon with a point total of 80 stop looking + // be [1, 2, 2, 4]. The Pokémon with a point total of 80 stop looking // when they see the first 80 in the array, so they both share the '2' // rank. for (i = 0; i < CONTESTANT_COUNT; i++) @@ -4585,10 +4585,10 @@ void MakeContestantNervous(u8 p) // ContestantStatus::nextTurnOrder field of each contestant. The remaining // turns are assigned such that the turn order will reverse. // -// For example, if no pokemon have a defined nextTurnOrder, then the 4th +// For example, if no Pokémon have a defined nextTurnOrder, then the 4th // will become 1st, the 3rd will become 2nd, etc. // -// Note: This function assumes that multiple pokemon cannot have the same +// Note: This function assumes that multiple Pokémon cannot have the same // nextTurnOrder value. static void ApplyNextTurnOrder(void) { diff --git a/src/credits.c b/src/credits.c index 2b4d919bdcc6..5d5a80cf78ed 100644 --- a/src/credits.c +++ b/src/credits.c @@ -64,12 +64,12 @@ enum { struct CreditsData { - u16 monToShow[NUM_MON_SLIDES]; // List of Pokemon species ids that will show during the credits + u16 monToShow[NUM_MON_SLIDES]; // List of Pokémon species ids that will show during the credits u16 imgCounter; //how many mon images have been shown u16 nextImgPos; //if the next image spawns left/center/right u16 currShownMon; //index into monToShow - u16 numMonToShow; //number of pokemon to show, always NUM_MON_SLIDES after determine function - u16 caughtMonIds[NATIONAL_DEX_COUNT]; //temporary location to hold a condensed array of all caught pokemon + u16 numMonToShow; //number of Pokémon to show, always NUM_MON_SLIDES after determine function + u16 caughtMonIds[NATIONAL_DEX_COUNT]; //temporary location to hold a condensed array of all caught Pokémon u16 numCaughtMon; //count of filled spaces in caughtMonIds u16 unused[7]; }; @@ -1556,8 +1556,8 @@ static void DeterminePokemonToShow(void) u16 dexNum; u16 j; - // Go through the Pokedex, and anything that has gotten caught we put into our massive array. - // This basically packs all of the caught pokemon into the front of the array + // Go through the Pokédex, and anything that has gotten caught we put into our massive array. + // This basically packs all of the caught Pokémon into the front of the array for (dexNum = 1, j = 0; dexNum < NATIONAL_DEX_COUNT; dexNum++) { if (GetSetPokedexFlag(dexNum, FLAG_GET_CAUGHT)) @@ -1571,14 +1571,14 @@ static void DeterminePokemonToShow(void) for (dexNum = j; dexNum < NATIONAL_DEX_COUNT; dexNum++) sCreditsData->caughtMonIds[dexNum] = NATIONAL_DEX_NONE; - // Cap the number of pokemon we care about to NUM_MON_SLIDES, the max we show in the credits scene (-1 for the starter) + // Cap the number of Pokémon we care about to NUM_MON_SLIDES, the max we show in the credits scene (-1 for the starter) sCreditsData->numCaughtMon = j; if (sCreditsData->numCaughtMon < NUM_MON_SLIDES) sCreditsData->numMonToShow = j; else sCreditsData->numMonToShow = NUM_MON_SLIDES; - // Loop through our list of caught pokemon and select randomly from it to fill the images to show + // Loop through our list of caught Pokémon and select randomly from it to fill the images to show j = 0; do { @@ -1599,7 +1599,7 @@ static void DeterminePokemonToShow(void) } while (sCreditsData->numCaughtMon != 0 && j < NUM_MON_SLIDES); - // If we don't have enough pokemon in the dex to fill everything, copy the selected mon into the end of the array, so it loops + // If we don't have enough Pokémon in the dex to fill everything, copy the selected mon into the end of the array, so it loops if (sCreditsData->numMonToShow < NUM_MON_SLIDES) { for (j = sCreditsData->numMonToShow, page = 0; j < NUM_MON_SLIDES; j++) @@ -1610,7 +1610,7 @@ static void DeterminePokemonToShow(void) if (page == sCreditsData->numMonToShow) page = 0; } - // Ensure the last pokemon is our starter + // Ensure the last Pokémon is our starter sCreditsData->monToShow[NUM_MON_SLIDES - 1] = starter; } else @@ -1618,7 +1618,7 @@ static void DeterminePokemonToShow(void) // Check to see if our starter has already appeared in this list, break if it has for (dexNum = 0; sCreditsData->monToShow[dexNum] != starter && dexNum < NUM_MON_SLIDES; dexNum++); - // If it has, swap it with the last pokemon, to ensure our starter is the last image + // If it has, swap it with the last Pokémon, to ensure our starter is the last image if (dexNum < sCreditsData->numMonToShow - 1) { sCreditsData->monToShow[dexNum] = sCreditsData->monToShow[NUM_MON_SLIDES-1]; @@ -1626,7 +1626,7 @@ static void DeterminePokemonToShow(void) } else { - // Ensure the last pokemon is our starter + // Ensure the last Pokémon is our starter sCreditsData->monToShow[NUM_MON_SLIDES - 1] = starter; } } diff --git a/src/crt0.s b/src/crt0.s index 580814722018..af6ea0bc9549 100644 --- a/src/crt0.s +++ b/src/crt0.s @@ -6,22 +6,28 @@ .align 2, 0 Init:: +@ Set up location for IRQ stack mov r0, #PSR_IRQ_MODE msr cpsr_cf, r0 ldr sp, sp_irq +@ Set up location for system stack 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] - .if MODERN +@ Dispatch memory reset request to hardware mov r0, #255 @ RESET_ALL svc #1 << 16 - .endif @ MODERN +@ Fill RAM areas with appropriate data + bl InitializeWorkingMemory +@ Jump to AgbMain ldr r1, =AgbMain + 1 mov lr, pc bx r1 +@ Re-init if AgbMain exits b Init .align 2, 0 @@ -124,3 +130,54 @@ IntrMain_RetAddr: .pool .align 2, 0 @ Don't pad with nop. + +@ Fills initialized IWRAM and EWRAM sections in RAM from LMA areas in ROM +InitializeWorkingMemory: + push {r0-r3,lr} + ldr r0, =__iwram_lma + ldr r1, =__iwram_start + ldr r2, =__iwram_end + cmp r1, r2 + beq skip_iwram_copy + bl CopyMemory_DMA +skip_iwram_copy: + ldr r0, =__ewram_lma + ldr r1, =__ewram_start + ldr r2, =__ewram_end + cmp r1, r2 + beq skip_ewram_copy + bl CopyMemory_DMA +skip_ewram_copy: + pop {r0-r3,lr} + bx lr + +@ Uses a DMA transfer to load from r0 into r1 until r2 +CopyMemory_DMA: + subs r2, r2, r1 + lsr r2, r2, #2 + mov r4, #0x80000000 + orr r4, r4, #(1 << 26) + orr r2, r2, r4 + ldr r3, =REG_DMA3 + stmia r3, {r0, r1, r2} + bx lr + +.thumb +@ Called from C code to reinitialize working memory after a link connection failure +ReInitializeEWRAM:: + ldr r0, =__ewram_lma + ldr r1, =__ewram_start + ldr r2, =__ewram_end + cmp r1, r2 + beq EndReinitializeEWRAM + subs r2, r1 + movs r3, #1 + lsls r3, r3, #26 + orrs r2, r2, r3 + swi 0x0B +EndReinitializeEWRAM: + bx lr + + .pool + + .align 2, 0 @ Don't pad with nop. diff --git a/src/data/abilities.h b/src/data/abilities.h index 2ff80f3ab371..81bfc995a364 100644 --- a/src/data/abilities.h +++ b/src/data/abilities.h @@ -4,84 +4,108 @@ const struct Ability gAbilities[ABILITIES_COUNT] = { .name = _("-------"), .description = COMPOUND_STRING("No special ability."), + .aiRating = 0, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_STENCH] = { .name = _("Stench"), .description = COMPOUND_STRING("May cause a foe to flinch."), + .aiRating = 1, }, [ABILITY_DRIZZLE] = { .name = _("Drizzle"), .description = COMPOUND_STRING("Summons rain in battle."), + .aiRating = 9, }, [ABILITY_SPEED_BOOST] = { .name = _("Speed Boost"), .description = COMPOUND_STRING("Gradually boosts Speed."), + .aiRating = 9, }, [ABILITY_BATTLE_ARMOR] = { .name = _("Battle Armor"), .description = COMPOUND_STRING("Blocks critical hits."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_STURDY] = { .name = _("Sturdy"), .description = COMPOUND_STRING("Negates 1-hit KO attacks."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_DAMP] = { .name = _("Damp"), .description = COMPOUND_STRING("Prevents self-destruction."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_LIMBER] = { .name = _("Limber"), .description = COMPOUND_STRING("Prevents paralysis."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SAND_VEIL] = { .name = _("Sand Veil"), .description = COMPOUND_STRING("Ups evasion in a sandstorm."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_STATIC] = { .name = _("Static"), .description = COMPOUND_STRING("Paralyzes on contact."), + .aiRating = 4, }, [ABILITY_VOLT_ABSORB] = { .name = _("Volt Absorb"), .description = COMPOUND_STRING("Turns electricity into HP."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_WATER_ABSORB] = { .name = _("Water Absorb"), .description = COMPOUND_STRING("Changes water into HP."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_OBLIVIOUS] = { .name = _("Oblivious"), .description = COMPOUND_STRING("Prevents attraction."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_CLOUD_NINE] = { .name = _("Cloud Nine"), .description = COMPOUND_STRING("Negates weather effects."), + .aiRating = 5, }, [ABILITY_COMPOUND_EYES] = @@ -92,102 +116,130 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("CompoundEyes"), #endif .description = COMPOUND_STRING("Raises accuracy."), + .aiRating = 7, }, [ABILITY_INSOMNIA] = { .name = _("Insomnia"), .description = COMPOUND_STRING("Prevents sleep."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_COLOR_CHANGE] = { .name = _("Color Change"), .description = COMPOUND_STRING("Changes type to foe's move."), + .aiRating = 2, }, [ABILITY_IMMUNITY] = { .name = _("Immunity"), .description = COMPOUND_STRING("Prevents poisoning."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_FLASH_FIRE] = { .name = _("Flash Fire"), .description = COMPOUND_STRING("Powers up if hit by fire."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SHIELD_DUST] = { .name = _("Shield Dust"), .description = COMPOUND_STRING("Prevents added effects."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_OWN_TEMPO] = { .name = _("Own Tempo"), .description = COMPOUND_STRING("Prevents confusion."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SUCTION_CUPS] = { .name = _("Suction Cups"), .description = COMPOUND_STRING("Firmly anchors the body."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_INTIMIDATE] = { .name = _("Intimidate"), .description = COMPOUND_STRING("Lowers the foe's Attack."), + .aiRating = 7, }, [ABILITY_SHADOW_TAG] = { .name = _("Shadow Tag"), .description = COMPOUND_STRING("Prevents the foe's escape."), + .aiRating = 10, }, [ABILITY_ROUGH_SKIN] = { .name = _("Rough Skin"), .description = COMPOUND_STRING("Hurts to touch."), + .aiRating = 6, }, [ABILITY_WONDER_GUARD] = { .name = _("Wonder Guard"), .description = COMPOUND_STRING("“Supereffective” hits."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .breakable = TRUE, }, [ABILITY_LEVITATE] = { .name = _("Levitate"), .description = COMPOUND_STRING("Not hit by Ground attacks."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_EFFECT_SPORE] = { .name = _("Effect Spore"), .description = COMPOUND_STRING("Leaves spores on contact."), + .aiRating = 4, }, [ABILITY_SYNCHRONIZE] = { .name = _("Synchronize"), .description = COMPOUND_STRING("Passes on status problems."), + .aiRating = 4, }, [ABILITY_CLEAR_BODY] = { .name = _("Clear Body"), .description = COMPOUND_STRING("Prevents ability reduction."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_NATURAL_CURE] = { .name = _("Natural Cure"), .description = COMPOUND_STRING("Heals upon switching out."), + .aiRating = 7, }, [ABILITY_LIGHTNING_ROD] = @@ -198,870 +250,1075 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("LightningRod"), #endif .description = COMPOUND_STRING("Draws electrical moves."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_SERENE_GRACE] = { .name = _("Serene Grace"), .description = COMPOUND_STRING("Promotes added effects."), + .aiRating = 8, }, [ABILITY_SWIFT_SWIM] = { .name = _("Swift Swim"), .description = COMPOUND_STRING("Raises Speed in rain."), + .aiRating = 6, }, [ABILITY_CHLOROPHYLL] = { .name = _("Chlorophyll"), .description = COMPOUND_STRING("Raises Speed in sunshine."), + .aiRating = 6, }, [ABILITY_ILLUMINATE] = { .name = _("Illuminate"), .description = COMPOUND_STRING("Encounter rate increases."), + .aiRating = 0, + .breakable = TRUE, }, [ABILITY_TRACE] = { .name = _("Trace"), .description = COMPOUND_STRING("Copies special ability."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_HUGE_POWER] = { .name = _("Huge Power"), .description = COMPOUND_STRING("Raises Attack."), + .aiRating = 10, }, [ABILITY_POISON_POINT] = { .name = _("Poison Point"), .description = COMPOUND_STRING("Poisons foe on contact."), + .aiRating = 4, }, [ABILITY_INNER_FOCUS] = { .name = _("Inner Focus"), .description = COMPOUND_STRING("Prevents flinching."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MAGMA_ARMOR] = { .name = _("Magma Armor"), .description = COMPOUND_STRING("Prevents freezing."), + .aiRating = 1, + .breakable = TRUE, }, [ABILITY_WATER_VEIL] = { .name = _("Water Veil"), .description = COMPOUND_STRING("Prevents burns."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_MAGNET_PULL] = { .name = _("Magnet Pull"), .description = COMPOUND_STRING("Traps Steel-type Pokémon."), + .aiRating = 9, }, [ABILITY_SOUNDPROOF] = { .name = _("Soundproof"), .description = COMPOUND_STRING("Avoids sound-based moves."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_RAIN_DISH] = { .name = _("Rain Dish"), .description = COMPOUND_STRING("Slight HP recovery in rain."), + .aiRating = 3, }, [ABILITY_SAND_STREAM] = { .name = _("Sand Stream"), .description = COMPOUND_STRING("Summons a sandstorm."), + .aiRating = 9, }, [ABILITY_PRESSURE] = { .name = _("Pressure"), .description = COMPOUND_STRING("Raises foe's PP usage."), + .aiRating = 5, }, [ABILITY_THICK_FAT] = { .name = _("Thick Fat"), .description = COMPOUND_STRING("Heat-and-cold protection."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_EARLY_BIRD] = { .name = _("Early Bird"), .description = COMPOUND_STRING("Awakens quickly from sleep."), + .aiRating = 4, }, [ABILITY_FLAME_BODY] = { .name = _("Flame Body"), .description = COMPOUND_STRING("Burns the foe on contact."), + .aiRating = 4, }, [ABILITY_RUN_AWAY] = { .name = _("Run Away"), .description = COMPOUND_STRING("Makes escaping easier."), + .aiRating = 0, }, [ABILITY_KEEN_EYE] = { .name = _("Keen Eye"), .description = COMPOUND_STRING("Prevents loss of accuracy."), + .aiRating = 1, + .breakable = TRUE, }, [ABILITY_HYPER_CUTTER] = { .name = _("Hyper Cutter"), .description = COMPOUND_STRING("Prevents Attack reduction."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_PICKUP] = { .name = _("Pickup"), .description = COMPOUND_STRING("May pick up items."), + .aiRating = 1, }, [ABILITY_TRUANT] = { .name = _("Truant"), .description = COMPOUND_STRING("Moves only every two turns."), + .aiRating = -2, + .cantBeOverwritten = TRUE, }, [ABILITY_HUSTLE] = { .name = _("Hustle"), .description = COMPOUND_STRING("Trades accuracy for power."), + .aiRating = 7, }, [ABILITY_CUTE_CHARM] = { .name = _("Cute Charm"), .description = COMPOUND_STRING("Infatuates on contact."), + .aiRating = 2, }, [ABILITY_PLUS] = { .name = _("Plus"), .description = COMPOUND_STRING("Powers up with Minus."), + .aiRating = 0, }, [ABILITY_MINUS] = { .name = _("Minus"), .description = COMPOUND_STRING("Powers up with Plus."), + .aiRating = 0, }, [ABILITY_FORECAST] = { .name = _("Forecast"), .description = COMPOUND_STRING("Changes with the weather."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_STICKY_HOLD] = { .name = _("Sticky Hold"), .description = COMPOUND_STRING("Prevents item theft."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_SHED_SKIN] = { .name = _("Shed Skin"), .description = COMPOUND_STRING("Heals the body by shedding."), + .aiRating = 7, }, [ABILITY_GUTS] = { .name = _("Guts"), .description = COMPOUND_STRING("Ups Attack if suffering."), + .aiRating = 6, }, [ABILITY_MARVEL_SCALE] = { .name = _("Marvel Scale"), .description = COMPOUND_STRING("Ups Defense if suffering."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_LIQUID_OOZE] = { .name = _("Liquid Ooze"), .description = COMPOUND_STRING("Draining causes injury."), + .aiRating = 3, }, [ABILITY_OVERGROW] = { .name = _("Overgrow"), .description = COMPOUND_STRING("Ups Grass moves in a pinch."), + .aiRating = 5, }, [ABILITY_BLAZE] = { .name = _("Blaze"), .description = COMPOUND_STRING("Ups Fire moves in a pinch."), + .aiRating = 5, }, [ABILITY_TORRENT] = { .name = _("Torrent"), .description = COMPOUND_STRING("Ups Water moves in a pinch."), + .aiRating = 5, }, [ABILITY_SWARM] = { .name = _("Swarm"), .description = COMPOUND_STRING("Ups Bug moves in a pinch."), + .aiRating = 5, }, [ABILITY_ROCK_HEAD] = { .name = _("Rock Head"), .description = COMPOUND_STRING("Prevents recoil damage."), + .aiRating = 5, }, [ABILITY_DROUGHT] = { .name = _("Drought"), .description = COMPOUND_STRING("Summons sunlight in battle."), + .aiRating = 9, }, [ABILITY_ARENA_TRAP] = { .name = _("Arena Trap"), .description = COMPOUND_STRING("Prevents fleeing."), + .aiRating = 9, }, [ABILITY_VITAL_SPIRIT] = { .name = _("Vital Spirit"), .description = COMPOUND_STRING("Prevents sleep."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_WHITE_SMOKE] = { .name = _("White Smoke"), .description = COMPOUND_STRING("Prevents ability reduction."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_PURE_POWER] = { .name = _("Pure Power"), .description = COMPOUND_STRING("Raises Attack."), + .aiRating = 10, }, [ABILITY_SHELL_ARMOR] = { .name = _("Shell Armor"), .description = COMPOUND_STRING("Blocks critical hits."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_AIR_LOCK] = { .name = _("Air Lock"), .description = COMPOUND_STRING("Negates weather effects."), + .aiRating = 5, }, [ABILITY_TANGLED_FEET] = { .name = _("Tangled Feet"), .description = COMPOUND_STRING("Ups evasion if confused."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MOTOR_DRIVE] = { .name = _("Motor Drive"), .description = COMPOUND_STRING("Electricity raises Speed."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_RIVALRY] = { .name = _("Rivalry"), .description = COMPOUND_STRING("Powers up against rivals."), + .aiRating = 1, }, [ABILITY_STEADFAST] = { .name = _("Steadfast"), .description = COMPOUND_STRING("Flinching raises Speed."), + .aiRating = 2, }, [ABILITY_SNOW_CLOAK] = { .name = _("Snow Cloak"), .description = COMPOUND_STRING("Ups evasion in Hail or Snow."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_GLUTTONY] = { .name = _("Gluttony"), .description = COMPOUND_STRING("Eats Berries early."), + .aiRating = 3, }, [ABILITY_ANGER_POINT] = { .name = _("Anger Point"), .description = COMPOUND_STRING("Critical hits raise Attack."), + .aiRating = 4, }, [ABILITY_UNBURDEN] = { .name = _("Unburden"), .description = COMPOUND_STRING("Using a hold item ups Speed."), + .aiRating = 7, }, [ABILITY_HEATPROOF] = { .name = _("Heatproof"), .description = COMPOUND_STRING("Heat and burn protection."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SIMPLE] = { .name = _("Simple"), .description = COMPOUND_STRING("Prone to wild stat changes."), + .aiRating = 8, + .breakable = TRUE, }, [ABILITY_DRY_SKIN] = { .name = _("Dry Skin"), .description = COMPOUND_STRING("Prefers moisture to heat."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_DOWNLOAD] = { .name = _("Download"), .description = COMPOUND_STRING("Adjusts power favorably."), + .aiRating = 7, }, [ABILITY_IRON_FIST] = { .name = _("Iron Fist"), .description = COMPOUND_STRING("Boosts punching moves."), + .aiRating = 6, }, [ABILITY_POISON_HEAL] = { .name = _("Poison Heal"), .description = COMPOUND_STRING("Restores HP if poisoned."), + .aiRating = 8, }, [ABILITY_ADAPTABILITY] = { .name = _("Adaptability"), .description = COMPOUND_STRING("Boosts same type attacks."), + .aiRating = 8, }, [ABILITY_SKILL_LINK] = { .name = _("Skill Link"), .description = COMPOUND_STRING("Multi-hit moves hit 5 times."), + .aiRating = 7, }, [ABILITY_HYDRATION] = { .name = _("Hydration"), .description = COMPOUND_STRING("Cures status in rain."), + .aiRating = 4, }, [ABILITY_SOLAR_POWER] = { .name = _("Solar Power"), .description = COMPOUND_STRING("Powers up in sunshine."), + .aiRating = 3, }, [ABILITY_QUICK_FEET] = { .name = _("Quick Feet"), .description = COMPOUND_STRING("Ups Speed if suffering."), + .aiRating = 5, }, [ABILITY_NORMALIZE] = { .name = _("Normalize"), .description = COMPOUND_STRING("Moves become Normal-type."), + .aiRating = -1, }, [ABILITY_SNIPER] = { .name = _("Sniper"), .description = COMPOUND_STRING("Boosts critical hits."), + .aiRating = 3, }, [ABILITY_MAGIC_GUARD] = { .name = _("Magic Guard"), .description = COMPOUND_STRING("Only damaged by attacks."), + .aiRating = 9, }, [ABILITY_NO_GUARD] = { .name = _("No Guard"), .description = COMPOUND_STRING("Ensures that all moves hit."), + .aiRating = 8, }, [ABILITY_STALL] = { .name = _("Stall"), .description = COMPOUND_STRING("Always moves last."), + .aiRating = -1, }, [ABILITY_TECHNICIAN] = { .name = _("Technician"), .description = COMPOUND_STRING("Boosts weaker moves."), + .aiRating = 8, }, [ABILITY_LEAF_GUARD] = { .name = _("Leaf Guard"), .description = COMPOUND_STRING("Blocks status in sunshine."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_KLUTZ] = { .name = _("Klutz"), .description = COMPOUND_STRING("Can't use hold items."), + .aiRating = -1, }, [ABILITY_MOLD_BREAKER] = { .name = _("Mold Breaker"), .description = COMPOUND_STRING("Moves hit through abilities."), + .aiRating = 7, }, [ABILITY_SUPER_LUCK] = { .name = _("Super Luck"), .description = COMPOUND_STRING("Critical hits land often."), + .aiRating = 3, }, [ABILITY_AFTERMATH] = { .name = _("Aftermath"), .description = COMPOUND_STRING("Fainting damages the foe."), + .aiRating = 5, }, [ABILITY_ANTICIPATION] = { .name = _("Anticipation"), .description = COMPOUND_STRING("Senses dangerous moves."), + .aiRating = 2, }, [ABILITY_FOREWARN] = { .name = _("Forewarn"), .description = COMPOUND_STRING("Determines a foe's move."), + .aiRating = 2, }, [ABILITY_UNAWARE] = { .name = _("Unaware"), .description = COMPOUND_STRING("Ignores stat changes."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_TINTED_LENS] = { .name = _("Tinted Lens"), .description = COMPOUND_STRING("Ups “not very effective”."), + .aiRating = 7, }, [ABILITY_FILTER] = { .name = _("Filter"), .description = COMPOUND_STRING("Weakens “supereffective”."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SLOW_START] = { .name = _("Slow Start"), .description = COMPOUND_STRING("Takes a while to get going."), + .aiRating = -2, }, [ABILITY_SCRAPPY] = { .name = _("Scrappy"), .description = COMPOUND_STRING("Hits Ghost-type Pokémon."), + .aiRating = 6, }, [ABILITY_STORM_DRAIN] = { .name = _("Storm Drain"), .description = COMPOUND_STRING("Draws in Water moves."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_ICE_BODY] = { .name = _("Ice Body"), .description = COMPOUND_STRING("HP recovery in Hail or Snow."), + .aiRating = 3, }, [ABILITY_SOLID_ROCK] = { .name = _("Solid Rock"), .description = COMPOUND_STRING("Weakens “supereffective”."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_SNOW_WARNING] = { .name = _("Snow Warning"), .description = COMPOUND_STRING("Summons a Hailstorm."), + .aiRating = 8, }, [ABILITY_HONEY_GATHER] = { .name = _("Honey Gather"), .description = COMPOUND_STRING("May gather Honey."), + .aiRating = 0, }, [ABILITY_FRISK] = { .name = _("Frisk"), .description = COMPOUND_STRING("Checks a foe's item."), + .aiRating = 3, }, [ABILITY_RECKLESS] = { .name = _("Reckless"), .description = COMPOUND_STRING("Boosts moves with recoil."), + .aiRating = 6, }, [ABILITY_MULTITYPE] = { .name = _("Multitype"), .description = COMPOUND_STRING("Changes type to its Plate."), + .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_FLOWER_GIFT] = { .name = _("Flower Gift"), .description = COMPOUND_STRING("Allies power up in sunshine."), + .aiRating = 4, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, + .breakable = TRUE, }, [ABILITY_BAD_DREAMS] = { .name = _("Bad Dreams"), .description = COMPOUND_STRING("Damages sleeping Pokémon."), + .aiRating = 4, }, [ABILITY_PICKPOCKET] = { .name = _("Pickpocket"), .description = COMPOUND_STRING("Steals the foe's held item."), + .aiRating = 3, }, [ABILITY_SHEER_FORCE] = { .name = _("Sheer Force"), .description = COMPOUND_STRING("Trades effects for power."), + .aiRating = 8, }, [ABILITY_CONTRARY] = { .name = _("Contrary"), .description = COMPOUND_STRING("Inverts stat changes."), + .aiRating = 8, + .breakable = TRUE, }, [ABILITY_UNNERVE] = { .name = _("Unnerve"), .description = COMPOUND_STRING("Foes can't eat Berries."), + .aiRating = 3, }, [ABILITY_DEFIANT] = { .name = _("Defiant"), .description = COMPOUND_STRING("Lowered stats up Attack."), + .aiRating = 5, }, [ABILITY_DEFEATIST] = { .name = _("Defeatist"), .description = COMPOUND_STRING("Gives up at half HP."), + .aiRating = -1, }, [ABILITY_CURSED_BODY] = { .name = _("Cursed Body"), .description = COMPOUND_STRING("Disables moves on contact."), + .aiRating = 4, }, [ABILITY_HEALER] = { .name = _("Healer"), .description = COMPOUND_STRING("Heals partner Pokémon."), + .aiRating = 0, }, [ABILITY_FRIEND_GUARD] = { .name = _("Friend Guard"), .description = COMPOUND_STRING("Lowers damage to partner."), + .aiRating = 0, + .breakable = TRUE, }, [ABILITY_WEAK_ARMOR] = { .name = _("Weak Armor"), .description = COMPOUND_STRING("Its stats change when hit."), + .aiRating = 2, }, [ABILITY_HEAVY_METAL] = { .name = _("Heavy Metal"), .description = COMPOUND_STRING("Doubles weight."), + .aiRating = -1, + .breakable = TRUE, }, [ABILITY_LIGHT_METAL] = { .name = _("Light Metal"), .description = COMPOUND_STRING("Halves weight."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_MULTISCALE] = { .name = _("Multiscale"), .description = COMPOUND_STRING("Halves damage at full HP."), + .aiRating = 8, + .breakable = TRUE, }, [ABILITY_TOXIC_BOOST] = { .name = _("Toxic Boost"), .description = COMPOUND_STRING("Ups Attack if poisoned."), + .aiRating = 6, }, [ABILITY_FLARE_BOOST] = { .name = _("Flare Boost"), .description = COMPOUND_STRING("Ups Sp. Atk if burned."), + .aiRating = 5, }, [ABILITY_HARVEST] = { .name = _("Harvest"), .description = COMPOUND_STRING("May recycle a used Berry."), + .aiRating = 5, }, [ABILITY_TELEPATHY] = { .name = _("Telepathy"), .description = COMPOUND_STRING("Can't be damaged by an ally."), + .aiRating = 0, + .breakable = TRUE, }, [ABILITY_MOODY] = { .name = _("Moody"), .description = COMPOUND_STRING("Stats change gradually."), + .aiRating = 10, }, [ABILITY_OVERCOAT] = { .name = _("Overcoat"), .description = COMPOUND_STRING("Blocks weather and powder."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_POISON_TOUCH] = { .name = _("Poison Touch"), .description = COMPOUND_STRING("Poisons foe on contact."), + .aiRating = 4, }, [ABILITY_REGENERATOR] = { .name = _("Regenerator"), .description = COMPOUND_STRING("Heals upon switching out."), + .aiRating = 8, }, [ABILITY_BIG_PECKS] = { .name = _("Big Pecks"), .description = COMPOUND_STRING("Prevents Defense loss."), + .aiRating = 1, + .breakable = TRUE, }, [ABILITY_SAND_RUSH] = { .name = _("Sand Rush"), .description = COMPOUND_STRING("Ups Speed in a sandstorm."), + .aiRating = 6, }, [ABILITY_WONDER_SKIN] = { .name = _("Wonder Skin"), .description = COMPOUND_STRING("May avoid status problems."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_ANALYTIC] = { .name = _("Analytic"), .description = COMPOUND_STRING("Moving last boosts power."), + .aiRating = 5, }, [ABILITY_ILLUSION] = { .name = _("Illusion"), .description = COMPOUND_STRING("Appears as a partner."), + .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_IMPOSTER] = { .name = _("Imposter"), .description = COMPOUND_STRING("Transforms into the foe."), + .aiRating = 9, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_INFILTRATOR] = { .name = _("Infiltrator"), .description = COMPOUND_STRING("Passes through barriers."), + .aiRating = 6, }, [ABILITY_MUMMY] = { .name = _("Mummy"), .description = COMPOUND_STRING("Spreads with contact."), + .aiRating = 5, }, [ABILITY_MOXIE] = { .name = _("Moxie"), .description = COMPOUND_STRING("KOs raise Attack."), + .aiRating = 7, }, [ABILITY_JUSTIFIED] = { .name = _("Justified"), .description = COMPOUND_STRING("Dark hits raise Attack."), + .aiRating = 4, }, [ABILITY_RATTLED] = { .name = _("Rattled"), .description = COMPOUND_STRING("Raises Speed when scared."), + .aiRating = 3, }, [ABILITY_MAGIC_BOUNCE] = { .name = _("Magic Bounce"), .description = COMPOUND_STRING("Reflects status moves."), + .aiRating = 9, + .breakable = TRUE, }, [ABILITY_SAP_SIPPER] = { .name = _("Sap Sipper"), .description = COMPOUND_STRING("Grass increases Attack."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_PRANKSTER] = { .name = _("Prankster"), .description = COMPOUND_STRING("Status moves go first."), + .aiRating = 8, }, [ABILITY_SAND_FORCE] = { .name = _("Sand Force"), .description = COMPOUND_STRING("Powers up in a sandstorm."), + .aiRating = 4, }, [ABILITY_IRON_BARBS] = { .name = _("Iron Barbs"), .description = COMPOUND_STRING("Hurts to touch."), + .aiRating = 6, }, [ABILITY_ZEN_MODE] = { .name = _("Zen Mode"), .description = COMPOUND_STRING("Transforms at half HP."), + .aiRating = -1, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = B_UPDATED_ABILITY_DATA >= GEN_7, }, [ABILITY_VICTORY_STAR] = { .name = _("Victory Star"), .description = COMPOUND_STRING("Raises party accuracy."), + .aiRating = 6, }, [ABILITY_TURBOBLAZE] = { .name = _("Turboblaze"), .description = COMPOUND_STRING("Moves hit through abilities."), + .aiRating = 7, }, [ABILITY_TERAVOLT] = { .name = _("Teravolt"), .description = COMPOUND_STRING("Moves hit through abilities."), + .aiRating = 7, }, [ABILITY_AROMA_VEIL] = { .name = _("Aroma Veil"), .description = COMPOUND_STRING("Prevents limiting of moves."), + .aiRating = 3, + .breakable = TRUE, }, [ABILITY_FLOWER_VEIL] = { .name = _("Flower Veil"), .description = COMPOUND_STRING("Protects Grass-types."), + .aiRating = 0, }, [ABILITY_CHEEK_POUCH] = { .name = _("Cheek Pouch"), .description = COMPOUND_STRING("Eating Berries restores HP."), + .aiRating = 4, }, [ABILITY_PROTEAN] = { .name = _("Protean"), .description = COMPOUND_STRING("Changes type to used move."), + .aiRating = 8, }, [ABILITY_FUR_COAT] = { .name = _("Fur Coat"), .description = COMPOUND_STRING("Raises Defense."), + .aiRating = 7, }, [ABILITY_MAGICIAN] = { .name = _("Magician"), .description = COMPOUND_STRING("Steals the foe's held item."), + .aiRating = 3, }, [ABILITY_BULLETPROOF] = { .name = _("Bulletproof"), .description = COMPOUND_STRING("Avoids some projectiles."), + .aiRating = 7, }, [ABILITY_COMPETITIVE] = { .name = _("Competitive"), .description = COMPOUND_STRING("Lowered stats up Sp. Atk."), + .aiRating = 5, }, [ABILITY_STRONG_JAW] = { .name = _("Strong Jaw"), .description = COMPOUND_STRING("Boosts biting moves."), + .aiRating = 6, }, [ABILITY_REFRIGERATE] = { .name = _("Refrigerate"), .description = COMPOUND_STRING("Normal moves become Ice."), + .aiRating = 8, }, [ABILITY_SWEET_VEIL] = { .name = _("Sweet Veil"), .description = COMPOUND_STRING("Prevents party from sleep."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_STANCE_CHANGE] = @@ -1072,12 +1329,19 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("StanceChange"), #endif .description = COMPOUND_STRING("Transforms as it battles."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_GALE_WINGS] = { .name = _("Gale Wings"), .description = COMPOUND_STRING("Flying moves go first."), + .aiRating = 6, }, [ABILITY_MEGA_LAUNCHER] = @@ -1088,42 +1352,50 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("MegaLauncher"), #endif .description = COMPOUND_STRING("Boosts pulse moves."), + .aiRating = 7, }, [ABILITY_GRASS_PELT] = { .name = _("Grass Pelt"), .description = COMPOUND_STRING("Ups Defense in grass."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_SYMBIOSIS] = { .name = _("Symbiosis"), .description = COMPOUND_STRING("Passes its item to an ally."), + .aiRating = 0, }, [ABILITY_TOUGH_CLAWS] = { .name = _("Tough Claws"), .description = COMPOUND_STRING("Boosts contact moves."), + .aiRating = 7, }, [ABILITY_PIXILATE] = { .name = _("Pixilate"), .description = COMPOUND_STRING("Normal moves become Fairy."), + .aiRating = 8, }, [ABILITY_GOOEY] = { .name = _("Gooey"), .description = COMPOUND_STRING("Lowers Speed on contact."), + .aiRating = 5, }, [ABILITY_AERILATE] = { .name = _("Aerilate"), .description = COMPOUND_STRING("Normal moves become Flying."), + .aiRating = 8, }, [ABILITY_PARENTAL_BOND] = @@ -1134,24 +1406,28 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ParentalBond"), #endif .description = COMPOUND_STRING("Moves hit twice."), + .aiRating = 10, }, [ABILITY_DARK_AURA] = { .name = _("Dark Aura"), .description = COMPOUND_STRING("Boosts Dark moves."), + .aiRating = 6, }, [ABILITY_FAIRY_AURA] = { .name = _("Fairy Aura"), .description = COMPOUND_STRING("Boosts Fairy moves."), + .aiRating = 6, }, [ABILITY_AURA_BREAK] = { .name = _("Aura Break"), .description = COMPOUND_STRING("Reverse aura abilities."), + .aiRating = 3, }, [ABILITY_PRIMORDIAL_SEA] = @@ -1162,6 +1438,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PrimrdialSea"), #endif .description = COMPOUND_STRING("Summons heavy rain."), + .aiRating = 10, }, [ABILITY_DESOLATE_LAND] = @@ -1172,24 +1449,28 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("DesolateLand"), #endif .description = COMPOUND_STRING("Summons intense sunlight."), + .aiRating = 10, }, [ABILITY_DELTA_STREAM] = { .name = _("Delta Stream"), .description = COMPOUND_STRING("Summons strong winds."), + .aiRating = 10, }, [ABILITY_STAMINA] = { .name = _("Stamina"), .description = COMPOUND_STRING("Boosts Defense when hit."), + .aiRating = 6, }, [ABILITY_WIMP_OUT] = { .name = _("Wimp Out"), .description = COMPOUND_STRING("Flees at half HP."), + .aiRating = 3, }, [ABILITY_EMERGENCY_EXIT] = @@ -1200,6 +1481,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("EmergncyExit"), #endif .description = COMPOUND_STRING("Flees at half HP."), + .aiRating = 3, }, [ABILITY_WATER_COMPACTION] = @@ -1210,96 +1492,133 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("WtrCmpaction"), #endif .description = COMPOUND_STRING("Water boosts Defense."), + .aiRating = 4, }, [ABILITY_MERCILESS] = { .name = _("Merciless"), .description = COMPOUND_STRING("Criticals poisoned foes."), + .aiRating = 4, }, [ABILITY_SHIELDS_DOWN] = { .name = _("Shields Down"), .description = COMPOUND_STRING("Shell breaks at half HP."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_STAKEOUT] = { .name = _("Stakeout"), .description = COMPOUND_STRING("Stronger as foes switch in."), + .aiRating = 6, }, [ABILITY_WATER_BUBBLE] = { .name = _("Water Bubble"), .description = COMPOUND_STRING("Guards from fire and burns."), + .aiRating = 8, }, [ABILITY_STEELWORKER] = { .name = _("Steelworker"), .description = COMPOUND_STRING("Powers up Steel moves."), + .aiRating = 6, }, [ABILITY_BERSERK] = { .name = _("Berserk"), .description = COMPOUND_STRING("Boosts Sp. Atk at low HP."), + .aiRating = 5, }, [ABILITY_SLUSH_RUSH] = { .name = _("Slush Rush"), .description = COMPOUND_STRING("Raises Speed in Hail or Snow."), + .aiRating = 5, }, [ABILITY_LONG_REACH] = { .name = _("Long Reach"), .description = COMPOUND_STRING("Never makes contact."), + .aiRating = 3, }, [ABILITY_LIQUID_VOICE] = { .name = _("Liquid Voice"), .description = COMPOUND_STRING("Makes sound moves Water."), + .aiRating = 5, }, [ABILITY_TRIAGE] = { .name = _("Triage"), .description = COMPOUND_STRING("Healing moves go first."), + .aiRating = 7, }, [ABILITY_GALVANIZE] = { .name = _("Galvanize"), .description = COMPOUND_STRING("Normal moves turn Electric."), + .aiRating = 8, }, [ABILITY_SURGE_SURFER] = { .name = _("Surge Surfer"), .description = COMPOUND_STRING("Faster on electricity."), + .aiRating = 4, }, [ABILITY_SCHOOLING] = { .name = _("Schooling"), .description = COMPOUND_STRING("Forms a school when strong."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_DISGUISE] = { .name = _("Disguise"), .description = COMPOUND_STRING("Decoy protects it once."), + .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_BATTLE_BOND] = { .name = _("Battle Bond"), .description = COMPOUND_STRING("Changes form after a KO."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_POWER_CONSTRUCT] = @@ -1310,18 +1629,31 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PwrConstruct"), #endif .description = COMPOUND_STRING("Cells aid it when weakened."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_CORROSION] = { .name = _("Corrosion"), .description = COMPOUND_STRING("Poisons any type."), + .aiRating = 5, }, [ABILITY_COMATOSE] = { .name = _("Comatose"), .description = COMPOUND_STRING("Always drowsing."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_QUEENLY_MAJESTY] = @@ -1332,42 +1664,52 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("QueenlyMjsty"), #endif .description = COMPOUND_STRING("Protects from priority."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_INNARDS_OUT] = { .name = _("Innards Out"), .description = COMPOUND_STRING("Hurts foe when defeated."), + .aiRating = 5, }, [ABILITY_DANCER] = { .name = _("Dancer"), .description = COMPOUND_STRING("Dances along with others."), + .aiRating = 5, }, [ABILITY_BATTERY] = { .name = _("Battery"), .description = COMPOUND_STRING("Boosts ally's Sp. Atk."), + .aiRating = 0, }, [ABILITY_FLUFFY] = { .name = _("Fluffy"), .description = COMPOUND_STRING("Tougher but flammable."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_DAZZLING] = { .name = _("Dazzling"), .description = COMPOUND_STRING("Protects from priority."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SOUL_HEART] = { .name = _("Soul-Heart"), .description = COMPOUND_STRING("KOs raise Sp. Atk."), + .aiRating = 7, }, [ABILITY_TANGLING_HAIR] = @@ -1378,12 +1720,16 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("TanglingHair"), #endif .description = COMPOUND_STRING("Lowers Speed on contact."), + .aiRating = 5, }, [ABILITY_RECEIVER] = { .name = _("Receiver"), .description = COMPOUND_STRING("Copies ally's ability."), + .aiRating = 0, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_POWER_OF_ALCHEMY] = @@ -1394,18 +1740,28 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PwrOfAlchemy"), #endif .description = COMPOUND_STRING("Copies ally's ability."), + .aiRating = 0, + .cantBeCopied = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_BEAST_BOOST] = { .name = _("Beast Boost"), .description = COMPOUND_STRING("KOs boost best stat."), + .aiRating = 7, }, [ABILITY_RKS_SYSTEM] = { .name = _("RKS System"), .description = COMPOUND_STRING("Memories change its type."), + .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_ELECTRIC_SURGE] = @@ -1416,6 +1772,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ElectrcSurge"), #endif .description = COMPOUND_STRING("Field becomes Electric."), + .aiRating = 8, }, [ABILITY_PSYCHIC_SURGE] = @@ -1426,18 +1783,21 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PsychicSurge"), #endif .description = COMPOUND_STRING("Field becomes weird."), + .aiRating = 8, }, [ABILITY_MISTY_SURGE] = { .name = _("Misty Surge"), .description = COMPOUND_STRING("Field becomes misty."), + .aiRating = 8, }, [ABILITY_GRASSY_SURGE] = { .name = _("Grassy Surge"), .description = COMPOUND_STRING("Field becomes grassy."), + .aiRating = 8, }, [ABILITY_FULL_METAL_BODY] = @@ -1448,6 +1808,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("FullMetalBdy"), #endif .description = COMPOUND_STRING("Prevents stat reduction."), + .aiRating = 4, }, [ABILITY_SHADOW_SHIELD] = @@ -1458,18 +1819,21 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ShadowShield"), #endif .description = COMPOUND_STRING("Halves damage at full HP."), + .aiRating = 8, }, [ABILITY_PRISM_ARMOR] = { .name = _("Prism Armor"), .description = COMPOUND_STRING("Weakens “supereffective”."), + .aiRating = 6, }, [ABILITY_NEUROFORCE] = { .name = _("Neuroforce"), .description = COMPOUND_STRING("Ups “supereffective”."), + .aiRating = 6, }, [ABILITY_INTREPID_SWORD] = @@ -1480,6 +1844,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("IntrepidSwrd"), #endif .description = COMPOUND_STRING("Ups Attack on entry."), + .aiRating = 3, }, [ABILITY_DAUNTLESS_SHIELD] = @@ -1490,6 +1855,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("DauntlssShld"), #endif .description = COMPOUND_STRING("Ups Defense on entry."), + .aiRating = 3, }, [ABILITY_LIBERO] = @@ -1502,12 +1868,14 @@ const struct Ability gAbilities[ABILITIES_COUNT] = { .name = _("Ball Fetch"), .description = COMPOUND_STRING("Fetches failed Poké Ball."), + .aiRating = 0, }, [ABILITY_COTTON_DOWN] = { .name = _("Cotton Down"), .description = COMPOUND_STRING("Lower Speed of all when hit."), + .aiRating = 3, }, [ABILITY_PROPELLER_TAIL] = @@ -1518,72 +1886,97 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PropellrTail"), #endif .description = COMPOUND_STRING("Ignores foe's redirection."), + .aiRating = 2, }, [ABILITY_MIRROR_ARMOR] = { .name = _("Mirror Armor"), .description = COMPOUND_STRING("Reflect stat decreases."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_GULP_MISSILE] = { .name = _("Gulp Missile"), .description = COMPOUND_STRING("If hit, spits prey from sea."), + .aiRating = 3, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_STALWART] = { .name = _("Stalwart"), .description = COMPOUND_STRING("Ignores foe's redirection."), + .aiRating = 2, }, [ABILITY_STEAM_ENGINE] = { .name = _("Steam Engine"), .description = COMPOUND_STRING("Fire or Water hits up Speed."), + .aiRating = 3, }, [ABILITY_PUNK_ROCK] = { .name = _("Punk Rock"), .description = COMPOUND_STRING("Ups and resists sound."), + .aiRating = 2, + .breakable = TRUE, }, [ABILITY_SAND_SPIT] = { .name = _("Sand Spit"), .description = COMPOUND_STRING("Creates a sandstorm if hit."), + .aiRating = 5, }, [ABILITY_ICE_SCALES] = { .name = _("Ice Scales"), .description = COMPOUND_STRING("Halves special damage."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_RIPEN] = { .name = _("Ripen"), .description = COMPOUND_STRING("Doubles effect of Berries."), + .aiRating = 4, }, [ABILITY_ICE_FACE] = { .name = _("Ice Face"), .description = COMPOUND_STRING("Hail or Snow renew free hit."), + .aiRating = 4, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .breakable = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_POWER_SPOT] = { .name = _("Power Spot"), .description = COMPOUND_STRING("Powers up ally moves."), + .aiRating = 2, }, [ABILITY_MIMICRY] = { .name = _("Mimicry"), .description = COMPOUND_STRING("Changes type on terrain."), + .aiRating = 2, }, [ABILITY_SCREEN_CLEANER] = @@ -1594,6 +1987,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ScreenCleanr"), #endif .description = COMPOUND_STRING("Removes walls of light."), + .aiRating = 3, }, [ABILITY_STEELY_SPIRIT] = @@ -1604,12 +1998,14 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("SteelySpirit"), #endif .description = COMPOUND_STRING("Boosts ally's Steel moves."), + .aiRating = 2, }, [ABILITY_PERISH_BODY] = { .name = _("Perish Body"), .description = COMPOUND_STRING("Foe faints in 3 turns if hit."), + .aiRating = -1, }, [ABILITY_WANDERING_SPIRIT] = @@ -1620,6 +2016,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("WandrngSprit"), #endif .description = COMPOUND_STRING("Trade abilities on contact."), + .aiRating = 2, }, [ABILITY_GORILLA_TACTICS] = @@ -1630,6 +2027,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("GorillaTacti"), #endif .description = COMPOUND_STRING("Ups Attack and locks move."), + .aiRating = 4, }, [ABILITY_NEUTRALIZING_GAS] = @@ -1640,12 +2038,19 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("NeutrlzngGas"), #endif .description = COMPOUND_STRING("All Abilities are nullified."), + .aiRating = 5, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_PASTEL_VEIL] = { .name = _("Pastel Veil"), .description = COMPOUND_STRING("Protects team from poison."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_HUNGER_SWITCH] = @@ -1656,18 +2061,25 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("HungerSwitch"), #endif .description = COMPOUND_STRING("Changes form each turn."), + .aiRating = 2, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_QUICK_DRAW] = { .name = _("Quick Draw"), .description = COMPOUND_STRING("Moves first occasionally."), + .aiRating = 4, }, [ABILITY_UNSEEN_FIST] = { .name = _("Unseen Fist"), .description = COMPOUND_STRING("Contact evades protection."), + .aiRating = 6, }, [ABILITY_CURIOUS_MEDICINE] = @@ -1678,18 +2090,21 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("CuriusMedicn"), #endif .description = COMPOUND_STRING("Remove ally's stat changes."), + .aiRating = 3, }, [ABILITY_TRANSISTOR] = { .name = _("Transistor"), .description = COMPOUND_STRING("Ups Electric-type moves."), + .aiRating = 6, }, [ABILITY_DRAGONS_MAW] = { .name = _("Dragon's Maw"), .description = COMPOUND_STRING("Ups Dragon-type moves."), + .aiRating = 6, }, [ABILITY_CHILLING_NEIGH] = @@ -1700,24 +2115,38 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ChillngNeigh"), #endif .description = COMPOUND_STRING("KOs boost Attack stat."), + .aiRating = 7, }, [ABILITY_GRIM_NEIGH] = { .name = _("Grim Neigh"), .description = COMPOUND_STRING("KOs boost Sp. Atk stat."), + .aiRating = 7, }, [ABILITY_AS_ONE_ICE_RIDER] = { .name = _("As One"), .description = COMPOUND_STRING("Unnerve and Chilling Neigh."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_AS_ONE_SHADOW_RIDER] = { .name = _("As One"), .description = COMPOUND_STRING("Unnerve and Grim Neigh."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, }, [ABILITY_LINGERING_AROMA] = @@ -1728,12 +2157,14 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("LngerngAroma"), #endif .description = COMPOUND_STRING("Spreads with contact."), + .aiRating = 5, }, [ABILITY_SEED_SOWER] = { .name = _("Seed Sower"), .description = COMPOUND_STRING("Affects terrain when hit."), + .aiRating = 5, }, [ABILITY_THERMAL_EXCHANGE] = @@ -1744,12 +2175,15 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("ThrmlExchnge"), #endif .description = COMPOUND_STRING("Fire hits up Attack."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_ANGER_SHELL] = { .name = _("Anger Shell"), .description = COMPOUND_STRING("Gets angry at half HP."), + .aiRating = 3, }, [ABILITY_PURIFYING_SALT] = @@ -1760,6 +2194,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PurfyingSalt"), #endif .description = COMPOUND_STRING("Protected by pure salts."), + .aiRating = 6, + .breakable = TRUE, }, [ABILITY_WELL_BAKED_BODY] = @@ -1770,18 +2206,24 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("WellBakedBdy"), #endif .description = COMPOUND_STRING("Strengthened by Fire."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_WIND_RIDER] = { .name = _("Wind Rider"), .description = COMPOUND_STRING("Ups Attack if hit by wind."), + .aiRating = 4, + .breakable = TRUE, }, [ABILITY_GUARD_DOG] = { .name = _("Guard Dog"), .description = COMPOUND_STRING("Cannot be intimidated."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_ROCKY_PAYLOAD] = @@ -1792,24 +2234,37 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("RockyPayload"), #endif .description = COMPOUND_STRING("Powers up Rock moves."), + .aiRating = 6, }, [ABILITY_WIND_POWER] = { .name = _("Wind Power"), .description = COMPOUND_STRING("Gets charged by wind."), + .aiRating = 4, }, [ABILITY_ZERO_TO_HERO] = { .name = _("Zero to Hero"), .description = COMPOUND_STRING("Changes form on switch out."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_COMMANDER] = { .name = _("Commander"), .description = COMPOUND_STRING("Commands from Dondozo."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_ELECTROMORPHOSIS] = @@ -1819,7 +2274,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #else .name = _("Elecmrphosis"), #endif - .description = COMPOUND_STRING("Gets Charged on contact."), + .description = COMPOUND_STRING("Gets Charged when hit."), + .aiRating = 5, }, [ABILITY_PROTOSYNTHESIS] = @@ -1830,18 +2286,30 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("Protosnthsis"), #endif .description = COMPOUND_STRING("Sun boosts best stat."), + .aiRating = 7, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_QUARK_DRIVE] = { .name = _("Quark Drive"), .description = COMPOUND_STRING("Elec. field ups best stat."), + .aiRating = 7, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_GOOD_AS_GOLD] = { .name = _("Good as Gold"), .description = COMPOUND_STRING("Avoids status problems."), + .aiRating = 8, + .breakable = TRUE, }, [ABILITY_VESSEL_OF_RUIN] = @@ -1852,6 +2320,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("VesselOfRuin"), #endif .description = COMPOUND_STRING("Lowers foes' sp. damage."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_SWORD_OF_RUIN] = @@ -1861,7 +2331,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #else .name = _("SwordOfRuin"), #endif - .description = COMPOUND_STRING("Lowers foes' defense."), + .description = COMPOUND_STRING("Lowers foes' Defense."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_TABLETS_OF_RUIN] = @@ -1872,6 +2344,8 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("TabltsOfRuin"), #endif .description = COMPOUND_STRING("Lowers foes' damage."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_BEADS_OF_RUIN] = @@ -1881,7 +2355,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = #else .name = _("BeadsOfRuin"), #endif - .description = COMPOUND_STRING("Lowers foes' sp. defense."), + .description = COMPOUND_STRING("Lowers foes' Sp. Defense."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_ORICHALCUM_PULSE] = @@ -1892,6 +2368,7 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("OrchlcumPlse"), #endif .description = COMPOUND_STRING("Summons sunlight in battle."), + .aiRating = 8, }, [ABILITY_HADRON_ENGINE] = @@ -1902,24 +2379,28 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("HadronEngine"), #endif .description = COMPOUND_STRING("Field becomes Electric."), + .aiRating = 8, }, [ABILITY_OPPORTUNIST] = { .name = _("Opportunist"), .description = COMPOUND_STRING("Copies foe's stat change."), + .aiRating = 5, }, [ABILITY_CUD_CHEW] = { .name = _("Cud Chew"), .description = COMPOUND_STRING("Eats a used berry again."), + .aiRating = 4, }, [ABILITY_SHARPNESS] = { .name = _("Sharpness"), .description = COMPOUND_STRING("Strengthens slicing moves."), + .aiRating = 7, }, [ABILITY_SUPREME_OVERLORD] = @@ -1930,30 +2411,37 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("SuprmeOvrlrd"), #endif .description = COMPOUND_STRING("Inherits fallen's strength."), + .aiRating = 6, }, [ABILITY_COSTAR] = { .name = _("Costar"), .description = COMPOUND_STRING("Copies ally's stat changes."), + .aiRating = 5, }, [ABILITY_TOXIC_DEBRIS] = { .name = _("Toxic Debris"), .description = COMPOUND_STRING("Throws poison spikes if hit."), + .aiRating = 4, }, [ABILITY_ARMOR_TAIL] = { .name = _("Armor Tail"), .description = COMPOUND_STRING("Protects from priority."), + .aiRating = 5, + .breakable = TRUE, }, [ABILITY_EARTH_EATER] = { .name = _("Earth Eater"), .description = COMPOUND_STRING("Eats ground to heal HP."), + .aiRating = 7, + .breakable = TRUE, }, [ABILITY_MYCELIUM_MIGHT] = @@ -1964,18 +2452,22 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("MceliumMight"), #endif .description = COMPOUND_STRING("Status moves never fail."), + .aiRating = 2, }, [ABILITY_HOSPITALITY] = { .name = _("Hospitality"), .description = COMPOUND_STRING("Restores ally's HP."), + .aiRating = 5, }, [ABILITY_MINDS_EYE] = { .name = _("Mind's Eye"), .description = COMPOUND_STRING("Keen Eye and Scrappy."), + .aiRating = 8, + .breakable = TRUE, }, [ABILITY_EMBODY_ASPECT_TEAL] = @@ -1986,6 +2478,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("EmbodyAspect"), #endif .description = COMPOUND_STRING("Raises Speed."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = @@ -1996,6 +2493,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("EmbodyAspect"), #endif .description = COMPOUND_STRING("Raises Attack."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_WELLSPRING] = @@ -2006,6 +2508,11 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("EmbodyAspect"), #endif .description = COMPOUND_STRING("Raises Sp. Def."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_EMBODY_ASPECT_CORNERSTONE] = @@ -2016,12 +2523,18 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("EmbodyAspect"), #endif .description = COMPOUND_STRING("Raises Defense."), + .aiRating = 6, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_TOXIC_CHAIN] = { .name = _("Toxic Chain"), .description = COMPOUND_STRING("Moves can poison."), + .aiRating = 8, }, [ABILITY_SUPERSWEET_SYRUP] = @@ -2032,18 +2545,31 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("SuprswtSyrup"), #endif .description = COMPOUND_STRING("Lowers the foe's Speed."), + .aiRating = 5, }, [ABILITY_TERA_SHIFT] = { .name = _("Tera Shift"), .description = COMPOUND_STRING("Terasteralizes upon entry."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .cantBeSuppressed = TRUE, + .cantBeOverwritten = TRUE, + .failsOnImposter = TRUE, }, [ABILITY_TERA_SHELL] = { .name = _("Tera Shell"), .description = COMPOUND_STRING("Resistant to types at full HP."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, + .breakable = TRUE, }, [ABILITY_TERAFORM_ZERO] = @@ -2054,6 +2580,10 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("TeraformZero"), #endif .description = COMPOUND_STRING("Removes weather and terrain."), + .aiRating = 10, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, [ABILITY_POISON_PUPPETEER] = @@ -2064,5 +2594,9 @@ const struct Ability gAbilities[ABILITIES_COUNT] = .name = _("PoisnPuppter"), #endif .description = COMPOUND_STRING("Confuses poisoned foes."), + .aiRating = 8, + .cantBeCopied = TRUE, + .cantBeSwapped = TRUE, + .cantBeTraced = TRUE, }, }; diff --git a/src/data/battle_frontier/battle_frontier_trainer_mons.h b/src/data/battle_frontier/battle_frontier_trainer_mons.h index 625a602658c5..f0a203d56d90 100644 --- a/src/data/battle_frontier/battle_frontier_trainer_mons.h +++ b/src/data/battle_frontier/battle_frontier_trainer_mons.h @@ -4172,7 +4172,7 @@ FRONTIER_MON_##lastmon##_10,\ -1 -// The strong Psychic M/F trainers all use the below pokemon +// The strong Psychic M/F trainers all use the below Pokémon // Additionally they use 1 of 3 legendary trios, and Latios or Latias depending on gender #define FRONTIER_MONS_PSYCHIC_2(lati, legend1, legend2, legend3) \ FRONTIER_MON_WOBBUFFET_1, \ diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 4e26d9e4b3f5..ea4876f67fa3 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -11310,7 +11310,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .accuracy = 100, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_SPECIAL, .ignoresTargetAbility = TRUE, @@ -13887,7 +13887,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_IVY_CUDGEL] = { - .effect = EFFECT_CHANGE_TYPE_ON_ITEM, + .effect = EFFECT_IVY_CUDGEL, .power = 100, .type = TYPE_GRASS, .accuracy = 100, @@ -13897,13 +13897,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_PHYSICAL, - .argument = HOLD_EFFECT_MASK, .metronomeBanned = TRUE, }, [MOVE_ELECTRO_SHOT] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_ELECTRO_SHOT + .effect = EFFECT_METEOR_BEAM, .power = 130, .type = TYPE_ELECTRIC, .accuracy = 100, @@ -13934,7 +13933,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_FICKLE_BEAM] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_FICKLE_BEAM + .effect = EFFECT_FICKLE_BEAM, .power = 80, .type = TYPE_DRAGON, .accuracy = 100, @@ -13947,7 +13946,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_BURNING_BULWARK] = { - .effect = EFFECT_PROTECT, // NEEDS ACTUAL PROTECT SIDE EFFECT + .effect = EFFECT_PROTECT, .power = 0, .type = TYPE_FIRE, .accuracy = 0, @@ -14038,16 +14037,17 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_ALLURING_VOICE] = { - .effect = EFFECT_PLACEHOLDER, //EFFECT_ALLURING_VOICE + .effect = EFFECT_CONFUSE_HIT, .power = 80, .type = TYPE_FAIRY, .accuracy = 100, .pp = 10, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_SPECIAL, .soundMove = TRUE, + .sheerForceBoost = TRUE, .ignoresSubstitute = TRUE, }, diff --git a/src/data/graphics/pokemon.h b/src/data/graphics/pokemon.h index 68dc95295257..643f65e25138 100644 --- a/src/data/graphics/pokemon.h +++ b/src/data/graphics/pokemon.h @@ -9269,6 +9269,13 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonShinyPalette_Dipplin[] = INCBIN_U32("graphics/pokemon/dipplin/shiny.gbapal.lz"); const u8 gMonIcon_Dipplin[] = INCBIN_U8("graphics/pokemon/dipplin/icon.4bpp"); // const u8 gMonFootprint_Dipplin[] = INCBIN_U8("graphics/pokemon/dipplin/footprint.1bpp"); + + // const u32 gMonFrontPic_Hydrapple[] = INCBIN_U32("graphics/pokemon/hydrapple/front.4bpp.lz"); + // const u32 gMonPalette_Hydrapple[] = INCBIN_U32("graphics/pokemon/hydrapple/normal.gbapal.lz"); + // const u32 gMonBackPic_Hydrapple[] = INCBIN_U32("graphics/pokemon/hydrapple/back.4bpp.lz"); + // const u32 gMonShinyPalette_Hydrapple[] = INCBIN_U32("graphics/pokemon/hydrapple/shiny.gbapal.lz"); + // const u8 gMonIcon_Hydrapple[] = INCBIN_U8("graphics/pokemon/hydrapple/icon.4bpp"); + // const u8 gMonFootprint_Hydrapple[] = INCBIN_U8("graphics/pokemon/hydrapple/footprint.1bpp"); #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN @@ -9767,6 +9774,15 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar const u32 gMonShinyPalette_DuraludonGigantamax[] = INCBIN_U32("graphics/pokemon/duraludon/gigantamax/shiny.gbapal.lz"); const u8 gMonIcon_DuraludonGigantamax[] = INCBIN_U8("graphics/pokemon/duraludon/gigantamax/icon.4bpp"); #endif //P_GIGANTAMAX_FORMS + +#if P_GEN_9_CROSS_EVOS + // const u32 gMonFrontPic_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/front.4bpp.lz"); + // const u32 gMonPalette_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/normal.gbapal.lz"); + // const u32 gMonBackPic_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/back.4bpp.lz"); + // const u32 gMonShinyPalette_Archaludon[] = INCBIN_U32("graphics/pokemon/archaludon/shiny.gbapal.lz"); + // const u8 gMonIcon_Archaludon[] = INCBIN_U8("graphics/pokemon/archaludon/icon.4bpp"); + // const u8 gMonFootprint_Archaludon[] = INCBIN_U8("graphics/pokemon/archaludon/footprint.1bpp"); +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY @@ -10906,6 +10922,72 @@ const u8 gMonFootprint_QuestionMark[] = INCBIN_U8("graphics/pokemon/question_mar // const u32 gMonShinyPalette_OgerponCornerstoneMaskTera[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/tera/shiny.gbapal.lz"); #endif //P_FAMILY_OGERPON +#if P_FAMILY_GOUGING_FIRE + // const u32 gMonFrontPic_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/front.4bpp.lz"); + // const u32 gMonPalette_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/normal.gbapal.lz"); + // const u32 gMonBackPic_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/back.4bpp.lz"); + // const u32 gMonShinyPalette_GougingFire[] = INCBIN_U32("graphics/pokemon/gouging_fire/shiny.gbapal.lz"); + // const u8 gMonIcon_GougingFire[] = INCBIN_U8("graphics/pokemon/gouging_fire/icon.4bpp"); + // const u8 gMonFootprint_GougingFire[] = INCBIN_U8("graphics/pokemon/gouging_fire/footprint.1bpp"); +#endif //P_FAMILY_GOUGING_FIRE + +#if P_FAMILY_RAGING_BOLT + // const u32 gMonFrontPic_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/front.4bpp.lz"); + // const u32 gMonPalette_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/normal.gbapal.lz"); + // const u32 gMonBackPic_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/back.4bpp.lz"); + // const u32 gMonShinyPalette_RagingBolt[] = INCBIN_U32("graphics/pokemon/raging_bolt/shiny.gbapal.lz"); + // const u8 gMonIcon_RagingBolt[] = INCBIN_U8("graphics/pokemon/raging_bolt/icon.4bpp"); + // const u8 gMonFootprint_RagingBolt[] = INCBIN_U8("graphics/pokemon/raging_bolt/footprint.1bpp"); +#endif //P_FAMILY_RAGING_BOLT + +#if P_FAMILY_IRON_BOULDER + // const u32 gMonFrontPic_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/front.4bpp.lz"); + // const u32 gMonPalette_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/normal.gbapal.lz"); + // const u32 gMonBackPic_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/back.4bpp.lz"); + // const u32 gMonShinyPalette_IronBoulder[] = INCBIN_U32("graphics/pokemon/iron_boulder/shiny.gbapal.lz"); + // const u8 gMonIcon_IronBoulder[] = INCBIN_U8("graphics/pokemon/iron_boulder/icon.4bpp"); + // const u8 gMonFootprint_IronBoulder[] = INCBIN_U8("graphics/pokemon/iron_boulder/footprint.1bpp"); +#endif //P_FAMILY_IRON_BOULDER + +#if P_FAMILY_IRON_CROWN + // const u32 gMonFrontPic_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/front.4bpp.lz"); + // const u32 gMonPalette_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/normal.gbapal.lz"); + // const u32 gMonBackPic_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/back.4bpp.lz"); + // const u32 gMonShinyPalette_IronCrown[] = INCBIN_U32("graphics/pokemon/iron_crown/shiny.gbapal.lz"); + // const u8 gMonIcon_IronCrown[] = INCBIN_U8("graphics/pokemon/iron_crown/icon.4bpp"); + // const u8 gMonFootprint_IronCrown[] = INCBIN_U8("graphics/pokemon/iron_crown/footprint.1bpp"); +#endif //P_FAMILY_IRON_CROWN + +#if P_FAMILY_TERAPAGOS + // const u32 gMonFrontPic_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/front.4bpp.lz"); + // const u32 gMonPalette_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/normal.gbapal.lz"); + // const u32 gMonBackPic_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/back.4bpp.lz"); + // const u32 gMonShinyPalette_TerapagosNormal[] = INCBIN_U32("graphics/pokemon/terapagos/shiny.gbapal.lz"); + // const u8 gMonIcon_TerapagosNormal[] = INCBIN_U8("graphics/pokemon/terapagos/icon.4bpp"); + // const u8 gMonFootprint_Terapagos[] = INCBIN_U8("graphics/pokemon/terapagos/footprint.1bpp"); + + // const u32 gMonFrontPic_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/front.4bpp.lz"); + // const u32 gMonPalette_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/normal.gbapal.lz"); + // const u32 gMonBackPic_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/back.4bpp.lz"); + // const u32 gMonShinyPalette_TerapagosTerastal[] = INCBIN_U32("graphics/pokemon/terapagos/terastal/shiny.gbapal.lz"); + // const u8 gMonIcon_TerapagosTerastal[] = INCBIN_U8("graphics/pokemon/terapagos/terastal/icon.4bpp"); + + // const u32 gMonFrontPic_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/front.4bpp.lz"); + // const u32 gMonPalette_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/normal.gbapal.lz"); + // const u32 gMonBackPic_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/back.4bpp.lz"); + // const u32 gMonShinyPalette_TerapagosStellar[] = INCBIN_U32("graphics/pokemon/terapagos/stellar/shiny.gbapal.lz"); + // const u8 gMonIcon_TerapagosStellar[] = INCBIN_U8("graphics/pokemon/terapagos/stellar/icon.4bpp"); +#endif //P_FAMILY_TERAPAGOS + +#if P_FAMILY_PECHARUNT + // const u32 gMonFrontPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/front.4bpp.lz"); + // const u32 gMonPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/normal.gbapal.lz"); + // const u32 gMonBackPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/back.4bpp.lz"); + // const u32 gMonShinyPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/shiny.gbapal.lz"); + // const u8 gMonIcon_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/icon.4bpp"); + // const u8 gMonFootprint_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/footprint.1bpp"); +#endif //P_FAMILY_PECHARUNT + const u32 gMonFrontPic_Egg[] = INCBIN_U32("graphics/pokemon/egg/anim_front.4bpp.lz"); const u32 gMonPalette_Egg[] = INCBIN_U32("graphics/pokemon/egg/normal.gbapal.lz"); const u8 gMonIcon_Egg[] = INCBIN_U8("graphics/pokemon/egg/icon.4bpp"); diff --git a/src/data/items.h b/src/data/items.h index adf76d2f39ff..4ac253b15241 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -11292,42 +11292,36 @@ const struct Item gItems[] = { .name = _("CornrstneMask"), .price = 0, - .holdEffect = HOLD_EFFECT_MASK, .description = COMPOUND_STRING("Allows Ogerpon to\n" "wield the Rock-\n" "type in battle."), .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, .fieldUseFunc = ItemUseOutOfBattle_CannotUse, - .secondaryId = TYPE_ROCK, }, [ITEM_WELLSPRING_MASK] = { .name = _("WellsprngMask"), .price = 0, - .holdEffect = HOLD_EFFECT_MASK, .description = COMPOUND_STRING("Allows Ogerpon to\n" "wield the Water-\n" "type in battle."), .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, .fieldUseFunc = ItemUseOutOfBattle_CannotUse, - .secondaryId = TYPE_WATER, }, [ITEM_HEARTHFLAME_MASK] = { .name = _("HrthflameMask"), .price = 0, - .holdEffect = HOLD_EFFECT_MASK, .description = COMPOUND_STRING("Allows Ogerpon to\n" "wield the Fire-\n" "type in battle."), .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, .fieldUseFunc = ItemUseOutOfBattle_CannotUse, - .secondaryId = TYPE_FIRE, }, [ITEM_HEALTH_MOCHI] = diff --git a/src/data/party_menu.h b/src/data/party_menu.h index 168520a48c44..a053754f46b9 100644 --- a/src/data/party_menu.h +++ b/src/data/party_menu.h @@ -64,7 +64,7 @@ static const struct PartyMenuBoxInfoRects sPartyBoxInfoRects[] = // Each layout array has an array for each of the 6 party slots // The array for each slot has the sprite coords of its various sprites in the following order -// Pokemon icon (x, y), held item (x, y), status condition (x, y), menu pokeball (x, y) +// Pokémon icon (x, y), held item (x, y), status condition (x, y), menu Poké Ball (x, y) static const u8 sPartyMenuSpriteCoords[PARTY_LAYOUT_COUNT][PARTY_SIZE][4 * 2] = { [PARTY_LAYOUT_SINGLE] = @@ -953,7 +953,7 @@ static const struct CompressedSpritePalette sSpritePalette_MenuPokeball = gPartyMenuPokeball_Pal, TAG_POKEBALL }; -// Used for the pokeball sprite on each party slot / Cancel button +// Used for the Poké Ball sprite on each party slot / Cancel button static const struct SpriteTemplate sSpriteTemplate_MenuPokeball = { .tileTag = TAG_POKEBALL, diff --git a/src/data/pokemon/experience_tables.h b/src/data/pokemon/experience_tables.h index 15bcadeb29c3..8f50e1091856 100644 --- a/src/data/pokemon/experience_tables.h +++ b/src/data/pokemon/experience_tables.h @@ -1,5 +1,5 @@ -#define SQUARE(n)(n * n) -#define CUBE(n)(n * n * n) +#define SQUARE(n)((n) * (n)) +#define CUBE(n)((n) * (n) * (n)) #define EXP_SLOW(n)((5 * CUBE(n)) / 4) // (5 * (n)^3) / 4 #define EXP_FAST(n)((4 * CUBE(n)) / 5) // (4 * (n)^3) / 5 diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index 241178372885..62ba52dd02a2 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -1092,5 +1092,14 @@ static const struct FormChange sOgerponFormChangeTable[] = { }; #endif //P_FAMILY_OGERPON +#if P_FAMILY_TERAPAGOS +static const struct FormChange sTerapagosFormChangeTable[] = { + {FORM_CHANGE_BEGIN_BATTLE, SPECIES_TERAPAGOS_TERASTAL}, //needs to be tied to the ability + //{FORM_CHANGE_TERASTALLIZATION, SPECIES_TERAPAGOS_STELLAR}, + {FORM_CHANGE_END_BATTLE, SPECIES_TERAPAGOS_NORMAL}, + {FORM_CHANGE_TERMINATOR}, +}; +#endif //P_FAMILY_TERAPAGOS + #undef WHEN_LEARNED #undef WHEN_FORGOTTEN diff --git a/src/data/pokemon/form_species_tables.h b/src/data/pokemon/form_species_tables.h index b9d2631739d9..3fdd6dcbf585 100644 --- a/src/data/pokemon/form_species_tables.h +++ b/src/data/pokemon/form_species_tables.h @@ -1761,3 +1761,12 @@ static const u16 sOgerponFormSpeciesIdTable[] = { FORM_SPECIES_END, }; #endif //P_FAMILY_OGERPON + +#if P_FAMILY_TERAPAGOS +static const u16 sTerapagosFormSpeciesIdTable[] = { + SPECIES_TERAPAGOS_NORMAL, + SPECIES_TERAPAGOS_TERASTAL, + SPECIES_TERAPAGOS_STELLAR, + FORM_SPECIES_END, +}; +#endif //P_FAMILY_TERAPAGOS diff --git a/src/data/pokemon/item_effects.h b/src/data/pokemon/item_effects.h index 2c7401059ed7..4273610b5ef7 100644 --- a/src/data/pokemon/item_effects.h +++ b/src/data/pokemon/item_effects.h @@ -626,6 +626,10 @@ const u8 *const gItemEffectTable[ITEMS_COUNT] = [ITEM_BLACK_AUGURITE] = gItemEffect_EvoItem, [ITEM_LINKING_CORD] = gItemEffect_EvoItem, [ITEM_PEAT_BLOCK] = gItemEffect_EvoItem, + [ITEM_SYRUPY_APPLE] = gItemEffect_EvoItem, + [ITEM_UNREMARKABLE_TEACUP] = gItemEffect_EvoItem, + [ITEM_MASTERPIECE_TEACUP] = gItemEffect_EvoItem, + [ITEM_METAL_ALLOY] = gItemEffect_EvoItem, // Berries [ITEM_CHERI_BERRY] = gItemEffect_CheriBerry, diff --git a/src/data/pokemon/level_up_learnsets.h b/src/data/pokemon/level_up_learnsets.h index 3325cb2b8ae7..e41d0ca937d1 100644 --- a/src/data/pokemon/level_up_learnsets.h +++ b/src/data/pokemon/level_up_learnsets.h @@ -19855,6 +19855,26 @@ static const struct LevelUpMove sDipplinLevelUpLearnset[] = { LEVEL_UP_MOVE(44, MOVE_SUBSTITUTE), LEVEL_UP_END }; + +static const struct LevelUpMove sHydrappleLevelUpLearnset[] = { + LEVEL_UP_MOVE( 0, MOVE_FICKLE_BEAM), + LEVEL_UP_MOVE( 1, MOVE_WITHDRAW), + LEVEL_UP_MOVE( 1, MOVE_SWEET_SCENT), + LEVEL_UP_MOVE( 1, MOVE_RECYCLE), + LEVEL_UP_MOVE( 1, MOVE_ASTONISH), + LEVEL_UP_MOVE( 4, MOVE_DRAGON_TAIL), + LEVEL_UP_MOVE( 8, MOVE_GROWTH), + LEVEL_UP_MOVE(12, MOVE_DRAGON_BREATH), + LEVEL_UP_MOVE(16, MOVE_PROTECT), + LEVEL_UP_MOVE(20, MOVE_BULLET_SEED), + LEVEL_UP_MOVE(28, MOVE_SYRUP_BOMB), + LEVEL_UP_MOVE(32, MOVE_DRAGON_PULSE), + LEVEL_UP_MOVE(36, MOVE_RECOVER), + LEVEL_UP_MOVE(40, MOVE_ENERGY_BALL), + LEVEL_UP_MOVE(44, MOVE_SUBSTITUTE), + LEVEL_UP_MOVE(54, MOVE_POWER_WHIP), + LEVEL_UP_END +}; #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN @@ -20571,6 +20591,26 @@ static const struct LevelUpMove sDuraludonLevelUpLearnset[] = { LEVEL_UP_MOVE(66, MOVE_HYPER_BEAM), LEVEL_UP_END }; + +#if P_GEN_9_CROSS_EVOS +static const struct LevelUpMove sArchaludonLevelUpLearnset[] = { + LEVEL_UP_MOVE( 0, MOVE_ELECTRO_SHOT), + LEVEL_UP_MOVE( 1, MOVE_LEER), + LEVEL_UP_MOVE( 1, MOVE_METAL_CLAW), + LEVEL_UP_MOVE( 6, MOVE_ROCK_SMASH), + LEVEL_UP_MOVE(12, MOVE_HONE_CLAWS), + LEVEL_UP_MOVE(18, MOVE_METAL_SOUND), + LEVEL_UP_MOVE(24, MOVE_BREAKING_SWIPE), + LEVEL_UP_MOVE(30, MOVE_DRAGON_TAIL), + LEVEL_UP_MOVE(36, MOVE_IRON_DEFENSE), + LEVEL_UP_MOVE(42, MOVE_FOCUS_ENERGY), + LEVEL_UP_MOVE(48, MOVE_DRAGON_CLAW), + LEVEL_UP_MOVE(54, MOVE_FLASH_CANNON), + LEVEL_UP_MOVE(60, MOVE_METAL_BURST), + LEVEL_UP_MOVE(66, MOVE_HYPER_BEAM), + LEVEL_UP_END +}; +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY @@ -23146,4 +23186,133 @@ static const struct LevelUpMove sOgerponLevelUpLearnset[] = { LEVEL_UP_MOVE(66, MOVE_WOOD_HAMMER), LEVEL_UP_END }; -#endif +#endif //P_FAMILY_OGERPON + +#if P_FAMILY_GOUGING_FIRE +static const struct LevelUpMove sGougingFireLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_STOMP), + LEVEL_UP_MOVE( 1, MOVE_LEER), + LEVEL_UP_MOVE( 1, MOVE_INCINERATE), + LEVEL_UP_MOVE( 1, MOVE_SUNNY_DAY), + LEVEL_UP_MOVE( 7, MOVE_FIRE_FANG), + LEVEL_UP_MOVE(14, MOVE_HOWL), + LEVEL_UP_MOVE(21, MOVE_BITE), + LEVEL_UP_MOVE(28, MOVE_DRAGON_CLAW), + LEVEL_UP_MOVE(35, MOVE_CRUSH_CLAW), + LEVEL_UP_MOVE(42, MOVE_MORNING_SUN), + LEVEL_UP_MOVE(49, MOVE_BURNING_BULWARK), + LEVEL_UP_MOVE(56, MOVE_DRAGON_RUSH), + LEVEL_UP_MOVE(63, MOVE_FIRE_BLAST), + LEVEL_UP_MOVE(70, MOVE_LAVA_PLUME), + LEVEL_UP_MOVE(77, MOVE_OUTRAGE), + LEVEL_UP_MOVE(84, MOVE_FLARE_BLITZ), + LEVEL_UP_MOVE(91, MOVE_RAGING_FURY), + LEVEL_UP_END +}; +#endif //P_FAMILY_GOUGING_FIRE + +#if P_FAMILY_RAGING_BOLT +static const struct LevelUpMove sRagingBoltLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_TWISTER), + LEVEL_UP_MOVE( 1, MOVE_SUNNY_DAY), + LEVEL_UP_MOVE( 1, MOVE_SHOCK_WAVE), + LEVEL_UP_MOVE( 1, MOVE_STOMP), + LEVEL_UP_MOVE( 7, MOVE_CHARGE), + LEVEL_UP_MOVE(14, MOVE_DRAGON_BREATH), + LEVEL_UP_MOVE(21, MOVE_ELECTRIC_TERRAIN), + LEVEL_UP_MOVE(28, MOVE_DISCHARGE), + LEVEL_UP_MOVE(35, MOVE_DRAGON_TAIL), + LEVEL_UP_MOVE(42, MOVE_CALM_MIND), + LEVEL_UP_MOVE(49, MOVE_THUNDERCLAP), + LEVEL_UP_MOVE(56, MOVE_DRAGON_HAMMER), + LEVEL_UP_MOVE(63, MOVE_RISING_VOLTAGE), + LEVEL_UP_MOVE(70, MOVE_DRAGON_PULSE), + LEVEL_UP_MOVE(77, MOVE_ZAP_CANNON), + LEVEL_UP_MOVE(84, MOVE_BODY_PRESS), + LEVEL_UP_MOVE(91, MOVE_THUNDER), + LEVEL_UP_END +}; +#endif //P_FAMILY_RAGING_BOLT + +#if P_FAMILY_IRON_BOULDER +static const struct LevelUpMove sIronBoulderLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_HORN_ATTACK), + LEVEL_UP_MOVE( 1, MOVE_LEER), + LEVEL_UP_MOVE( 1, MOVE_ROCK_THROW), + LEVEL_UP_MOVE( 1, MOVE_ELECTRIC_TERRAIN), + LEVEL_UP_MOVE( 7, MOVE_QUICK_ATTACK), + LEVEL_UP_MOVE(14, MOVE_SLASH), + LEVEL_UP_MOVE(21, MOVE_AGILITY), + LEVEL_UP_MOVE(28, MOVE_PSYCHO_CUT), + LEVEL_UP_MOVE(35, MOVE_COUNTER), + LEVEL_UP_MOVE(42, MOVE_ROCK_TOMB), + LEVEL_UP_MOVE(49, MOVE_SACRED_SWORD), + LEVEL_UP_MOVE(56, MOVE_MIGHTY_CLEAVE), + LEVEL_UP_MOVE(63, MOVE_SWORDS_DANCE), + LEVEL_UP_MOVE(70, MOVE_MEGAHORN), + LEVEL_UP_MOVE(77, MOVE_QUICK_GUARD), + LEVEL_UP_MOVE(84, MOVE_STONE_EDGE), + LEVEL_UP_MOVE(91, MOVE_GIGA_IMPACT), + LEVEL_UP_END +}; +#endif //P_FAMILY_IRON_BOULDER + +#if P_FAMILY_IRON_CROWN +static const struct LevelUpMove sIronCrownLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_LEER), + LEVEL_UP_MOVE( 1, MOVE_ELECTRIC_TERRAIN), + LEVEL_UP_MOVE( 1, MOVE_CONFUSION), + LEVEL_UP_MOVE( 1, MOVE_METAL_CLAW), + LEVEL_UP_MOVE( 7, MOVE_SMART_STRIKE), + LEVEL_UP_MOVE(14, MOVE_SLASH), + LEVEL_UP_MOVE(21, MOVE_IRON_DEFENSE), + LEVEL_UP_MOVE(28, MOVE_PSYSHOCK), + LEVEL_UP_MOVE(35, MOVE_PSYCHO_CUT), + LEVEL_UP_MOVE(42, MOVE_FLASH_CANNON), + LEVEL_UP_MOVE(49, MOVE_SACRED_SWORD), + LEVEL_UP_MOVE(56, MOVE_TACHYON_CUTTER), + LEVEL_UP_MOVE(63, MOVE_FUTURE_SIGHT), + LEVEL_UP_MOVE(70, MOVE_VOLT_SWITCH), + LEVEL_UP_MOVE(77, MOVE_QUICK_GUARD), + LEVEL_UP_MOVE(84, MOVE_METAL_BURST), + LEVEL_UP_MOVE(91, MOVE_HYPER_BEAM), + LEVEL_UP_END +}; +#endif //P_FAMILY_IRON_CROWN + +#if P_FAMILY_TERAPAGOS +static const struct LevelUpMove sTerapagosLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_WITHDRAW), + LEVEL_UP_MOVE( 1, MOVE_TRI_ATTACK), + LEVEL_UP_MOVE( 1, MOVE_RAPID_SPIN), + LEVEL_UP_MOVE(10, MOVE_ANCIENT_POWER), + LEVEL_UP_MOVE(20, MOVE_HEADBUTT), + LEVEL_UP_MOVE(30, MOVE_PROTECT), + LEVEL_UP_MOVE(40, MOVE_EARTH_POWER), + LEVEL_UP_MOVE(50, MOVE_HEAVY_SLAM), + LEVEL_UP_MOVE(60, MOVE_TERA_STARSTORM), + LEVEL_UP_MOVE(70, MOVE_DOUBLE_EDGE), + LEVEL_UP_MOVE(80, MOVE_ROCK_POLISH), + LEVEL_UP_MOVE(90, MOVE_GYRO_BALL), + LEVEL_UP_END +}; +#endif //P_FAMILY_TERAPAGOS + +#if P_FAMILY_PECHARUNT +static const struct LevelUpMove sPecharuntLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_SMOG), + LEVEL_UP_MOVE( 1, MOVE_POISON_GAS), + LEVEL_UP_MOVE( 1, MOVE_MEMENTO), + LEVEL_UP_MOVE( 1, MOVE_ASTONISH), + LEVEL_UP_MOVE( 8, MOVE_WITHDRAW), + LEVEL_UP_MOVE(16, MOVE_DESTINY_BOND), + LEVEL_UP_MOVE(24, MOVE_FAKE_TEARS), + LEVEL_UP_MOVE(32, MOVE_PARTING_SHOT), + LEVEL_UP_MOVE(40, MOVE_SHADOW_BALL), + LEVEL_UP_MOVE(48, MOVE_MALIGNANT_CHAIN), + LEVEL_UP_MOVE(56, MOVE_TOXIC), + LEVEL_UP_MOVE(64, MOVE_NASTY_PLOT), + LEVEL_UP_MOVE(72, MOVE_RECOVER), + LEVEL_UP_END +}; +#endif //P_FAMILY_PECHARUNT diff --git a/src/data/pokemon/pokedex_orders.h b/src/data/pokemon/pokedex_orders.h index e877bbb17f94..f7bd77cf12f5 100644 --- a/src/data/pokemon/pokedex_orders.h +++ b/src/data/pokemon/pokedex_orders.h @@ -26,6 +26,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_ARBOLIVA, NATIONAL_DEX_ARCANINE, NATIONAL_DEX_ARCEUS, + NATIONAL_DEX_ARCHALUDON, NATIONAL_DEX_ARCHEN, NATIONAL_DEX_ARCHEOPS, NATIONAL_DEX_ARCTIBAX, @@ -361,6 +362,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_GOTHITA, NATIONAL_DEX_GOTHITELLE, NATIONAL_DEX_GOTHORITA, + NATIONAL_DEX_GOUGING_FIRE, NATIONAL_DEX_GOURGEIST, NATIONAL_DEX_GRAFAIAI, NATIONAL_DEX_GRANBULL, @@ -416,6 +418,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_HOUNDOUR, NATIONAL_DEX_HOUNDSTONE, NATIONAL_DEX_HUNTAIL, + NATIONAL_DEX_HYDRAPPLE, NATIONAL_DEX_HYDREIGON, NATIONAL_DEX_HYPNO, @@ -427,7 +430,9 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_INFERNAPE, NATIONAL_DEX_INKAY, NATIONAL_DEX_INTELEON, + NATIONAL_DEX_IRON_BOULDER, NATIONAL_DEX_IRON_BUNDLE, + NATIONAL_DEX_IRON_CROWN, NATIONAL_DEX_IRON_HANDS, NATIONAL_DEX_IRON_JUGULIS, NATIONAL_DEX_IRON_LEAVES, @@ -658,6 +663,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_PAWMO, NATIONAL_DEX_PAWMOT, NATIONAL_DEX_PAWNIARD, + NATIONAL_DEX_PECHARUNT, NATIONAL_DEX_PELIPPER, NATIONAL_DEX_PERRSERKER, NATIONAL_DEX_PERSIAN, @@ -715,6 +721,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_RABOOT, NATIONAL_DEX_RABSCA, + NATIONAL_DEX_RAGING_BOLT, NATIONAL_DEX_RAICHU, NATIONAL_DEX_RAIKOU, NATIONAL_DEX_RALTS, @@ -906,6 +913,7 @@ const u16 gPokedexOrder_Alphabetical[] = NATIONAL_DEX_TENTACOOL, NATIONAL_DEX_TENTACRUEL, NATIONAL_DEX_TEPIG, + NATIONAL_DEX_TERAPAGOS, NATIONAL_DEX_TERRAKION, NATIONAL_DEX_THIEVUL, NATIONAL_DEX_THROH, @@ -1078,6 +1086,7 @@ const u16 gPokedexOrder_Weight[] = //NATIONAL_DEX_MINIOR_CORE_INDIGO, //NATIONAL_DEX_MINIOR_CORE_VIOLET, NATIONAL_DEX_MILCERY, + NATIONAL_DEX_PECHARUNT, // 0.9 lbs / 0.4 kg NATIONAL_DEX_POLTEAGEIST, NATIONAL_DEX_CURSOLA, @@ -1397,6 +1406,7 @@ const u16 gPokedexOrder_Weight[] = //NATIONAL_DEX_MELOETTA_PIROUETTE, NATIONAL_DEX_PAWMO, NATIONAL_DEX_SMOLIV, + NATIONAL_DEX_TERAPAGOS,//_NORMAL // 14.6 lbs / 6.6 kg NATIONAL_DEX_RALTS, NATIONAL_DEX_WHIMSICOTT, @@ -1662,6 +1672,7 @@ const u16 gPokedexOrder_Weight[] = NATIONAL_DEX_CORVISQUIRE, NATIONAL_DEX_NACLI, NATIONAL_DEX_MASCHIFF, + //NATIONAL_DEX_TERAPAGOS_TERASTAL // 35.9 lbs / 16.3 kg NATIONAL_DEX_WHISMUR, NATIONAL_DEX_LILLIGANT, @@ -2281,6 +2292,7 @@ const u16 gPokedexOrder_Weight[] = NATIONAL_DEX_LATIOS, //NATIONAL_DEX_GUMSHOOS_TOTEM_SIZED, NATIONAL_DEX_SANDY_SHOCKS, + NATIONAL_DEX_ARCHALUDON, // 132.7 lbs / 60.2 kg NATIONAL_DEX_FINIZEN, NATIONAL_DEX_PALAFIN,//_ZERO, @@ -2377,6 +2389,7 @@ const u16 gPokedexOrder_Weight[] = NATIONAL_DEX_COFAGRIGUS, // 168.9 lbs / 76.6 kg NATIONAL_DEX_GOLDUCK, + //NATIONAL_DEX_TERAPAGOS_STELLAR // 170.6 lbs / 77.4 kg NATIONAL_DEX_CACTURNE, // 172.0 lbs / 78.0 kg @@ -2477,6 +2490,8 @@ const u16 gPokedexOrder_Weight[] = // 204.8 lbs / 92.9 kg NATIONAL_DEX_DARMANITAN,//_STANDARD_MODE, //NATIONAL_DEX_DARMANITAN_ZEN_MODE, + // 205.0 lbs / 93.0 kg + NATIONAL_DEX_HYDRAPPLE, // 208.6 lbs / 94.6 kg NATIONAL_DEX_BOUFFALANT, NATIONAL_DEX_SAMUROTT, @@ -2659,6 +2674,8 @@ const u16 gPokedexOrder_Weight[] = NATIONAL_DEX_ARCANINE, // 342.8 lbs / 155.5 kg //NATIONAL_DEX_VENUSAUR_MEGA, + // 343.9 lbs / 156.0 kg + NATIONAL_DEX_IRON_CROWN, // 352.7 lbs / 160.0 kg NATIONAL_DEX_HYDREIGON, NATIONAL_DEX_FARIGIRAF, @@ -2666,6 +2683,8 @@ const u16 gPokedexOrder_Weight[] = //NATIONAL_DEX_SABLEYE_MEGA, // 357.1 lbs / 162.0 kg NATIONAL_DEX_MILOTIC, + // 358.2 lbs / 162.5 kg + NATIONAL_DEX_IRON_BOULDER, // 370.4 lbs / 168.0 kg //NATIONAL_DEX_ARCANINE_HISUIAN, NATIONAL_DEX_LUNATONE, @@ -2859,6 +2878,8 @@ const u16 gPokedexOrder_Weight[] = // 1014.1 lbs / 460.0 kg NATIONAL_DEX_SNORLAX, //NATIONAL_DEX_NECROZMA_DUSK_MANE, + // 1058.2 lbs / 480.0 kg + NATIONAL_DEX_RAGING_BOLT, // 1080.3 lbs / 490.0 kg //NATIONAL_DEX_HOOPA_UNBOUND, // 1113.3 lbs / 505.0 kg @@ -2867,6 +2888,8 @@ const u16 gPokedexOrder_Weight[] = NATIONAL_DEX_STONJOURNER, // 1212.5 lbs / 550.0 kg NATIONAL_DEX_METAGROSS, + // 1300.7 lbs / 590.0 kg + NATIONAL_DEX_GOUGING_FIRE, // 1344.8 lbs / 610.0 kg //NATIONAL_DEX_ZYGARDE_COMPLETE, // 1433.8 lbs / 650.0 kg @@ -2965,6 +2988,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_RELLOR, NATIONAL_DEX_FLITTLE, NATIONAL_DEX_SINISTCHA, + NATIONAL_DEX_TERAPAGOS,//_NORMAL // 1'00" / 0.3m NATIONAL_DEX_CATERPIE, NATIONAL_DEX_WEEDLE, @@ -3129,6 +3153,8 @@ const u16 gPokedexOrder_Height[] = //NATIONAL_DEX_TATSUGIRI_DROOPY, //NATIONAL_DEX_TATSUGIRI_STRETCHY, NATIONAL_DEX_GIMMIGHOUL,//_CHEST, + //NATIONAL_DEX_TERAPAGOS_TERASTAL, + NATIONAL_DEX_PECHARUNT, // 0.4m NATIONAL_DEX_SPRIGATITO, NATIONAL_DEX_FUECOCO, @@ -3871,6 +3897,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_GLIMMORA, NATIONAL_DEX_WO_CHIEN, NATIONAL_DEX_IRON_LEAVES, + NATIONAL_DEX_IRON_BOULDER, // 5'03" / 1.6m NATIONAL_DEX_BLASTOISE, //NATIONAL_DEX_BLASTOISE_MEGA, @@ -3918,6 +3945,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_CYCLIZAR, NATIONAL_DEX_FLAMIGO, NATIONAL_DEX_IRON_THORNS, + NATIONAL_DEX_IRON_CROWN, // 5'07" / 1.7m NATIONAL_DEX_CHARIZARD, //NATIONAL_DEX_CHARIZARD_MEGA_X, @@ -3955,6 +3983,7 @@ const u16 gPokedexOrder_Height[] = //NATIONAL_DEX_GOURGEIST_SUPER, NATIONAL_DEX_VOLCANION, NATIONAL_DEX_CRABOMINABLE, + //NATIONAL_DEX_TERAPAGOS_STELLAR // 5'11" / 1.8m NATIONAL_DEX_DODRIO, NATIONAL_DEX_AERODACTYL, @@ -3993,6 +4022,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_CLODSIRE, NATIONAL_DEX_IRON_HANDS, NATIONAL_DEX_OKIDOGI, + NATIONAL_DEX_HYDRAPPLE, // 6'03" / 1.9m NATIONAL_DEX_ARCANINE, NATIONAL_DEX_RHYDON, @@ -4053,6 +4083,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_HOUNDSTONE, NATIONAL_DEX_KINGAMBIT, NATIONAL_DEX_ROARING_MOON, + NATIONAL_DEX_ARCHALUDON, // 6'11" / 2.1m //NATIONAL_DEX_AERODACTYL_MEGA, NATIONAL_DEX_SNORLAX, @@ -4198,6 +4229,7 @@ const u16 gPokedexOrder_Height[] = NATIONAL_DEX_GROUDON, NATIONAL_DEX_MIRAIDON, NATIONAL_DEX_WALKING_WAKE, + NATIONAL_DEX_GOUGING_FIRE, // 11'10" / 3.6m //NATIONAL_DEX_KYUREM_WHITE, NATIONAL_DEX_NAGANADEL, @@ -4229,6 +4261,7 @@ const u16 gPokedexOrder_Height[] = //NATIONAL_DEX_ZYGARDE_50_POWER_CONSTRUCT, // 17'01" / 5.2m NATIONAL_DEX_LUGIA, + NATIONAL_DEX_RAGING_BOLT, // 17'09" / 5.4m NATIONAL_DEX_DIALGA, // 18'01" / 5.5m diff --git a/src/data/pokemon/species_info/gen_8.h b/src/data/pokemon/species_info/gen_8.h index bcf77fcfa261..0bbd9b2f3ad0 100644 --- a/src/data/pokemon/species_info/gen_8.h +++ b/src/data/pokemon/species_info/gen_8.h @@ -1938,6 +1938,54 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = ICON(Dipplin, 1), //.footprint = gMonFootprint_Dipplin, LEARNSETS(Dipplin), + .evolutions = EVOLUTION({EVO_MOVE, MOVE_DRAGON_CHEER, SPECIES_HYDRAPPLE}), + }, + + [SPECIES_HYDRAPPLE] = + { + .baseHP = 106, + .baseAttack = 80, + .baseDefense = 110, + .baseSpeed = 44, + .baseSpAttack = 120, + .baseSpDefense = 80, + .types = { TYPE_GRASS, TYPE_DRAGON }, + .catchRate = 10, + .expYield = 170, //Currently unknown + .evYield_SpAttack = 3, + .genderRatio = PERCENT_FEMALE(50), + .eggCycles = 20, + .friendship = STANDARD_FRIENDSHIP, + .growthRate = GROWTH_ERRATIC, + .eggGroups = { EGG_GROUP_GRASS, EGG_GROUP_DRAGON }, + .abilities = { ABILITY_SUPERSWEET_SYRUP, ABILITY_REGENERATOR, ABILITY_STICKY_HOLD }, + .bodyColor = BODY_COLOR_GREEN, + .speciesName = _("Hydrapple"), + //.cryId = CRY_HYDRAPPLE, + .natDexNum = NATIONAL_DEX_HYDRAPPLE, + .categoryName = _("Apple Hydra"), + .height = 18, + .weight = 930, + .description = COMPOUND_STRING( + "These capricious syrpents have\n" + "banded together. On the rare\n" + "occasion that their moods align,\n" + "their true power is unleashed."), + .pokemonScale = 356, + .pokemonOffset = 17, + .trainerScale = 256, + .trainerOffset = 0, + //FRONT_PIC(Hydrapple, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_Hydrapple, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(Hydrapple, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(Hydrapple), + //ICON(Hydrapple, 0), + //.footprint = gMonFootprint_Hydrapple, + LEARNSETS(Hydrapple), }, #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN @@ -4215,6 +4263,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = //.backAnimId = BACK_ANIM_NONE, PALETTES(Duraludon), ICON(Duraludon, 0), + .evolutions = EVOLUTION({EVO_ITEM, ITEM_METAL_ALLOY, SPECIES_ARCHALUDON}), }, #if P_GIGANTAMAX_FORMS @@ -4244,6 +4293,55 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .isGigantamax = TRUE, }, #endif //P_GIGANTAMAX_FORMS + +#if P_GEN_9_CROSS_EVOS + [SPECIES_ARCHALUDON] = + { + .baseHP = 90, + .baseAttack = 105, + .baseDefense = 130, + .baseSpeed = 85, + .baseSpAttack = 125, + .baseSpDefense = 65, + .types = { TYPE_STEEL, TYPE_DRAGON }, + .catchRate = 10, + .expYield = 187, //Currently unknown + .evYield_Defense = 3, + .genderRatio = PERCENT_FEMALE(50), + .eggCycles = 30, + .friendship = STANDARD_FRIENDSHIP, + .growthRate = GROWTH_MEDIUM_FAST, + .eggGroups = { EGG_GROUP_MINERAL, EGG_GROUP_DRAGON }, + .abilities = { ABILITY_STAMINA, ABILITY_STURDY, ABILITY_STALWART }, + .bodyColor = BODY_COLOR_WHITE, + .speciesName = _("Archaludon"), + //.cryId = CRY_ARCHALUDON, + .natDexNum = NATIONAL_DEX_ARCHALUDON, + .categoryName = _("Alloy"), + .height = 20, + .weight = 600, + .description = COMPOUND_STRING( + "It gathers static electricity\n" + "from its surroundings. The beams\n" + "it launches when down on all fours\n" + "are tremendously powerful."), + .pokemonScale = 267, + .pokemonOffset = 2, + .trainerScale = 286, + .trainerOffset = 1, + //FRONT_PIC(Archaludon, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_Archaludon, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(Archaludon, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(Archaludon), + //ICON(Archaludon, 0), + //.footprint = gMonFootprint_Archaludon, + LEARNSETS(Archaludon), + }, +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY diff --git a/src/data/pokemon/species_info/gen_9.h b/src/data/pokemon/species_info/gen_9.h index 2f5f0ad76aa7..70e55ae32060 100644 --- a/src/data/pokemon/species_info/gen_9.h +++ b/src/data/pokemon/species_info/gen_9.h @@ -5026,7 +5026,9 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .height = 35, .weight = 2800, .description = COMPOUND_STRING( - "Ecology under research."), + "This ferocious creature is shrouded in\n" + "mystery. It's named after an aquatic\n" + "monster mentioned in an old journal."), .pokemonScale = 356, .pokemonOffset = 17, .trainerScale = 256, @@ -5073,7 +5075,9 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .height = 15, .weight = 1250, .description = COMPOUND_STRING( - "Ecology under analysis."), + "According to the few eyewitness accounts\n" + "that exist, it used its shining blades\n" + "to julienne large trees and boulders."), .pokemonScale = 356, .pokemonOffset = 17, .trainerScale = 256, @@ -5428,6 +5432,376 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = #endif //P_FAMILY_OGERPON +#if P_FAMILY_GOUGING_FIRE + [SPECIES_GOUGING_FIRE] = + { + .baseHP = 105, + .baseAttack = 115, + .baseDefense = 121, + .baseSpeed = 91, + .baseSpAttack = 65, + .baseSpDefense = 93, + .types = { TYPE_FIRE, TYPE_DRAGON }, + .catchRate = 10, + .expYield = 261, //Currently unknown + .evYield_Defense = 3, + .genderRatio = MON_GENDERLESS, + .eggCycles = 50, + .friendship = 0, + .growthRate = GROWTH_SLOW, + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, + .abilities = { ABILITY_PROTOSYNTHESIS, ABILITY_NONE }, + .bodyColor = BODY_COLOR_BROWN, + .isParadoxForm = TRUE, + .speciesName = _("GouginFire"), + //.cryId = CRY_GOUGING_FIRE, + .natDexNum = NATIONAL_DEX_GOUGING_FIRE, + .categoryName = _("Paradox"), + .height = 35, + .weight = 5900, + .description = COMPOUND_STRING( + "There are scant few reports of\n" + "this creature being sighted.\n" + "One short video shows it rampaging,\n" + "and spouting pillars of flame."), + .pokemonScale = 259, + .pokemonOffset = 0, + .trainerScale = 345, + .trainerOffset = 7, + //FRONT_PIC(GougingFire, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_GougingFire, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(GougingFire, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(GougingFire), + //ICON(GougingFire, 0), + //.footprint = gMonFootprint_GougingFire, + LEARNSETS(GougingFire), + }, +#endif //P_FAMILY_GOUGING_FIRE + +#if P_FAMILY_RAGING_BOLT + [SPECIES_RAGING_BOLT] = + { + .baseHP = 125, + .baseAttack = 73, + .baseDefense = 91, + .baseSpeed = 75, + .baseSpAttack = 137, + .baseSpDefense = 89, + .types = { TYPE_ELECTRIC, TYPE_DRAGON }, + .catchRate = 10, + .expYield = 261, //Currently unknown + .evYield_SpAttack = 3, + .genderRatio = MON_GENDERLESS, + .eggCycles = 50, + .friendship = 0, + .growthRate = GROWTH_SLOW, + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, + .abilities = { ABILITY_PROTOSYNTHESIS, ABILITY_NONE }, + .bodyColor = BODY_COLOR_YELLOW, + .isParadoxForm = TRUE, + .speciesName = _("RagingBolt"), + //.cryId = CRY_RAGING_BOLT, + .natDexNum = NATIONAL_DEX_RAGING_BOLT, + .categoryName = _("Paradox"), + .height = 52, + .weight = 4800, + .description = COMPOUND_STRING( + "It bears resemblance to a Pokémon\n" + "that became a hot topic for a short\n" + "while after a paranomal magazine\n" + "touted it as Raikou's ancestor."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 345, + .trainerOffset = 7, + //FRONT_PIC(RagingBolt, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_RagingBolt, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(RagingBolt, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(RagingBolt), + //ICON(RagingBolt, 0), + //.footprint = gMonFootprint_RagingBolt, + LEARNSETS(RagingBolt), + }, +#endif //P_FAMILY_RAGING_BOLT + +#if P_FAMILY_IRON_BOULDER + [SPECIES_IRON_BOULDER] = + { + .baseHP = 90, + .baseAttack = 120, + .baseDefense = 80, + .baseSpeed = 124, + .baseSpAttack = 68, + .baseSpDefense = 108, + .types = { TYPE_ROCK, TYPE_PSYCHIC }, + .catchRate = 10, + .expYield = 261, //Currently unknown + .evYield_Speed = 3, + .genderRatio = MON_GENDERLESS, + .eggCycles = 50, + .friendship = 0, + .growthRate = GROWTH_SLOW, + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, + .abilities = { ABILITY_QUARK_DRIVE, ABILITY_NONE }, + .bodyColor = BODY_COLOR_GRAY, + .isParadoxForm = TRUE, + .speciesName = _("IronBouldr"), + //.cryId = CRY_IRON_BOULDER, + .natDexNum = NATIONAL_DEX_IRON_BOULDER, + .categoryName = _("Paradox"), + .height = 15, + .weight = 1625, + .description = COMPOUND_STRING( + "It was named after a mysterious\n" + "object recorded in an old book.\n" + "Its body seems to be metallic."), + .pokemonScale = 256, + .pokemonOffset = 1, + .trainerScale = 336, + .trainerOffset = 4, + //FRONT_PIC(IronBoulder, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_IronBoulder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(IronBoulder, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(IronBoulder), + //ICON(IronBoulder, 0), + //.footprint = gMonFootprint_IronBoulder, + LEARNSETS(IronBoulder), + }, +#endif //P_FAMILY_IRON_BOULDER + +#if P_FAMILY_IRON_CROWN + [SPECIES_IRON_CROWN] = + { + .baseHP = 90, + .baseAttack = 72, + .baseDefense = 100, + .baseSpeed = 98, + .baseSpAttack = 122, + .baseSpDefense = 108, + .types = { TYPE_STEEL, TYPE_PSYCHIC }, + .catchRate = 10, + .expYield = 261, //Currently unknown + .evYield_SpAttack = 3, + .genderRatio = MON_GENDERLESS, + .eggCycles = 50, + .friendship = 0, + .growthRate = GROWTH_SLOW, + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, + .abilities = { ABILITY_QUARK_DRIVE, ABILITY_NONE }, + .bodyColor = BODY_COLOR_BLUE, + .isParadoxForm = TRUE, + .speciesName = _("Iron Crown"), + //.cryId = CRY_IRON_CROWN, + .natDexNum = NATIONAL_DEX_IRON_CROWN, + .categoryName = _("Paradox"), + .height = 16, + .weight = 1560, + .description = COMPOUND_STRING( + "It resembles a mysterious object\n" + "introduced in a paranormal magazine\n" + "as a cutting-edge weapon\n" + "shaped like Cobalion."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 365, + .trainerOffset = 7, + //FRONT_PIC(IronCrown, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_IronCrown, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(IronCrown, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(IronCrown), + //ICON(IronCrown, 0), + //.footprint = gMonFootprint_IronCrown, + LEARNSETS(IronCrown), + }, +#endif //P_FAMILY_IRON_CROWN + +#if P_FAMILY_TERAPAGOS +#define TERAPAGOS_MISC_INFO \ + .types = { TYPE_NORMAL, TYPE_NORMAL }, \ + .catchRate = 255, \ + .expYield = 275, \ + .genderRatio = PERCENT_FEMALE(50), \ + .eggCycles = 20, \ + .friendship = STANDARD_FRIENDSHIP, \ + .growthRate = GROWTH_SLOW, \ + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, \ + .bodyColor = BODY_COLOR_BLUE, \ + .speciesName = _("Terapagos"), \ + .natDexNum = NATIONAL_DEX_TERAPAGOS, \ + .categoryName = _("Tera"), \ + LEARNSETS(Terapagos), \ + .formSpeciesIdTable = sTerapagosFormSpeciesIdTable, \ + .formChangeTable = sTerapagosFormChangeTable, \ + .isLegendary = TRUE + //.cryId = CRY_TERAPAGOS, + //.footprint = gMonFootprint_Terapagos, + + [SPECIES_TERAPAGOS_NORMAL] = + { + TERAPAGOS_MISC_INFO, + .baseHP = 90, + .baseAttack = 65, + .baseDefense = 85, + .baseSpeed = 60, + .baseSpAttack = 65, + .baseSpDefense = 85, + .evYield_Defense = 1, + .abilities = { ABILITY_TERA_SHIFT, ABILITY_NONE }, + .height = 2, + .weight = 65, + .description = COMPOUND_STRING( + "Terapagos protects itself using its\n" + "power to transform energy into hard\n" + "crystals. This Pokémon is the source\n" + "of the Terastal phenomenon."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 365, + .trainerOffset = 7, + //FRONT_PIC(TerapagosNormal, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_TerapagosNormal, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(TerapagosNormal, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(TerapagosNormal), + //ICON(TerapagosNormal, 0), + }, + + [SPECIES_TERAPAGOS_TERASTAL] = + { + TERAPAGOS_MISC_INFO, + .baseHP = 95, + .baseAttack = 95, + .baseDefense = 110, + .baseSpeed = 85, + .baseSpAttack = 105, + .baseSpDefense = 110, + .evYield_Defense = 2, + .abilities = { ABILITY_TERA_SHELL, ABILITY_NONE }, + .height = 3, + .weight = 160, + .description = COMPOUND_STRING( + "The shell is made of crystallized\n" + "Terastal energy. When struck by a move,\n" + "this shell absorbs the move's energy\n" + "and transfers it to Terapagos."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 365, + .trainerOffset = 7, + //FRONT_PIC(TerapagosTerastal, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_TerapagosTerastal, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(TerapagosTerastal, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(TerapagosTerastal), + //ICON(TerapagosTerastal, 0), + }, + + [SPECIES_TERAPAGOS_STELLAR] = + { + TERAPAGOS_MISC_INFO, + .baseHP = 160, + .baseAttack = 105, + .baseDefense = 110, + .baseSpeed = 85, + .baseSpAttack = 130, + .baseSpDefense = 110, + .evYield_HP = 3, + .abilities = { ABILITY_TERAFORM_ZERO, ABILITY_NONE }, + .height = 17, + .weight = 770, + .description = COMPOUND_STRING( + "An old expedition journal describes the\n" + "sight of this Pokémon buried in the,\n" + "depths of the earth as resembling a\n" + "planet floating in space."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 365, + .trainerOffset = 7, + //FRONT_PIC(TerapagosStellar, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_TerapagosStellar, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(TerapagosStellar, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(TerapagosStellar), + //ICON(TerapagosStellar, 0), + }, +#endif //P_FAMILY_TERAPAGOS + +#if P_FAMILY_PECHARUNT + [SPECIES_PECHARUNT] = + { + .baseHP = 88, + .baseAttack = 88, + .baseDefense = 160, + .baseSpeed = 88, + .baseSpAttack = 88, + .baseSpDefense = 88, + .types = { TYPE_POISON, TYPE_GHOST }, + .catchRate = 3, + .expYield = 261, //Currently unknown + .evYield_Defense = 3, + .genderRatio = MON_GENDERLESS, + .eggCycles = 50, + .friendship = 0, + .growthRate = GROWTH_SLOW, + .eggGroups = { EGG_GROUP_NO_EGGS_DISCOVERED, EGG_GROUP_NO_EGGS_DISCOVERED }, + .abilities = { ABILITY_POISON_PUPPETEER, ABILITY_NONE }, + .bodyColor = BODY_COLOR_PURPLE, + .isMythical = TRUE, + .speciesName = _("Pecharunt"), + //.cryId = CRY_PECHARUNT, + .natDexNum = NATIONAL_DEX_PECHARUNT, + .categoryName = _("Subjugation"), + .height = 3, + .weight = 3, + .description = COMPOUND_STRING( + "It feeds others toxic mochi that\n" + "draw out desires and capabilities.\n" + "Those who eat the mochi fall under\n" + "Pecharunt's control, chained to its will."), + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 365, + .trainerOffset = 7, + //FRONT_PIC(Pecharunt, 64, 64), + .frontPicYOffset = 0, + .frontAnimFrames = sAnims_Pecharunt, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //BACK_PIC(Pecharunt, 64, 64), + .backPicYOffset = 0, + //.backAnimId = BACK_ANIM_NONE, + //PALETTES(Pecharunt), + //ICON(Pecharunt, 0), + //.footprint = gMonFootprint_Pecharunt, + LEARNSETS(Pecharunt), + }, +#endif //P_FAMILY_PECHARUNT + #ifdef __INTELLISENSE__ }; -#endif \ No newline at end of file +#endif diff --git a/src/data/pokemon/teachable_learnsets.h b/src/data/pokemon/teachable_learnsets.h index f274363f61a8..b8f2a39e301f 100644 --- a/src/data/pokemon/teachable_learnsets.h +++ b/src/data/pokemon/teachable_learnsets.h @@ -33821,6 +33821,10 @@ static const u16 sAppletunTeachableLearnset[] = { static const u16 sDipplinTeachableLearnset[] = { MOVE_UNAVAILABLE, }; + +static const u16 sHydrappleTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN @@ -34654,6 +34658,12 @@ static const u16 sDuraludonTeachableLearnset[] = { MOVE_THUNDER_WAVE, MOVE_UNAVAILABLE, }; + +#if P_GEN_9_CROSS_EVOS +static const u16 sArchaludonTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY @@ -39114,3 +39124,39 @@ static const u16 sOgerponTeachableLearnset[] = { MOVE_UNAVAILABLE, }; #endif //P_FAMILY_OGERPON + +#if P_FAMILY_GOUGING_FIRE +static const u16 sGougingFireTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_GOUGING_FIRE + +#if P_FAMILY_RAGING_BOLT +static const u16 sRagingBoltTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_RAGING_BOLT + +#if P_FAMILY_IRON_BOULDER +static const u16 sIronBoulderTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_IRON_BOULDER + +#if P_FAMILY_IRON_CROWN +static const u16 sIronCrownTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_IRON_CROWN + +#if P_FAMILY_TERAPAGOS +static const u16 sTerapagosTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_TERAPAGOS + +#if P_FAMILY_PECHARUNT +static const u16 sPecharuntTeachableLearnset[] = { + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_PECHARUNT diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h index 92c8c7729c85..77a3ef8d6910 100644 --- a/src/data/pokemon_graphics/front_pic_anims.h +++ b/src/data/pokemon_graphics/front_pic_anims.h @@ -6127,7 +6127,9 @@ static const union AnimCmd sAnim_Regigigas_1[] = ANIMCMD_FRAME(0, 5), ANIMCMD_END, }; +#endif //P_FAMILY_REGIGIGAS +#if P_FAMILY_GIRATINA static const union AnimCmd sAnim_GiratinaAltered_1[] = { ANIMCMD_FRAME(0, 12), @@ -6145,7 +6147,7 @@ static const union AnimCmd sAnim_GiratinaOrigin_1[] = ANIMCMD_FRAME(0, 10), ANIMCMD_END, }; -#endif //P_FAMILY_REGIGIGAS +#endif //P_FAMILY_GIRATINA #if P_FAMILY_CRESSELIA static const union AnimCmd sAnim_Cresselia_1[] = @@ -9565,6 +9567,7 @@ PLACEHOLDER_ANIM_SINGLE_FRAME(AppletunGigantamax); #if P_GEN_9_CROSS_EVOS PLACEHOLDER_ANIM_SINGLE_FRAME(Dipplin); +PLACEHOLDER_ANIM_SINGLE_FRAME(Hydrapple); #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN @@ -9716,6 +9719,10 @@ PLACEHOLDER_ANIM_SINGLE_FRAME(Duraludon); #if P_GIGANTAMAX_FORMS PLACEHOLDER_ANIM_SINGLE_FRAME(DuraludonGigantamax); #endif //P_GIGANTAMAX_FORMS + +#if P_GEN_9_CROSS_EVOS +PLACEHOLDER_ANIM_SINGLE_FRAME(Archaludon); +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY @@ -10082,6 +10089,32 @@ PLACEHOLDER_ANIM_SINGLE_FRAME(Fezandipiti); PLACEHOLDER_ANIM_SINGLE_FRAME(Ogerpon); #endif //P_FAMILY_OGERPON +#if P_FAMILY_GOUGING_FIRE +PLACEHOLDER_ANIM_SINGLE_FRAME(GougingFire); +#endif //P_FAMILY_GOUGING_FIRE + +#if P_FAMILY_RAGING_BOLT +PLACEHOLDER_ANIM_SINGLE_FRAME(RagingBolt); +#endif //P_FAMILY_RAGING_BOLT + +#if P_FAMILY_IRON_BOULDER +PLACEHOLDER_ANIM_SINGLE_FRAME(IronBoulder); +#endif //P_FAMILY_IRON_BOULDER + +#if P_FAMILY_IRON_CROWN +PLACEHOLDER_ANIM_SINGLE_FRAME(IronCrown); +#endif //P_FAMILY_IRON_CROWN + +#if P_FAMILY_TERAPAGOS +PLACEHOLDER_ANIM_SINGLE_FRAME(TerapagosNormal); +PLACEHOLDER_ANIM_SINGLE_FRAME(TerapagosTerastal); +PLACEHOLDER_ANIM_SINGLE_FRAME(TerapagosStellar); +#endif //P_FAMILY_TERAPAGOS + +#if P_FAMILY_PECHARUNT +PLACEHOLDER_ANIM_SINGLE_FRAME(Pecharunt); +#endif //P_FAMILY_PECHARUNT + static const union AnimCmd sAnim_Egg_1[] = { ANIMCMD_FRAME(0, 6), @@ -12339,6 +12372,7 @@ SINGLE_ANIMATION(AppletunGigantamax); #endif //P_GIGANTAMAX_FORMS #if P_GEN_9_CROSS_EVOS SINGLE_ANIMATION(Dipplin); +SINGLE_ANIMATION(Hydrapple); #endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_APPLIN #if P_FAMILY_SILICOBRA @@ -12446,6 +12480,9 @@ SINGLE_ANIMATION(Duraludon); #if P_GIGANTAMAX_FORMS SINGLE_ANIMATION(DuraludonGigantamax); #endif //P_GIGANTAMAX_FORMS +#if P_GEN_9_CROSS_EVOS +SINGLE_ANIMATION(Archaludon); +#endif //P_GEN_9_CROSS_EVOS #endif //P_FAMILY_DURALUDON #if P_FAMILY_DREEPY SINGLE_ANIMATION(Dreepy); @@ -12729,4 +12766,24 @@ SINGLE_ANIMATION(Fezandipiti); #if P_FAMILY_OGERPON SINGLE_ANIMATION(Ogerpon); #endif //P_FAMILY_OGERPON +#if P_FAMILY_GOUGING_FIRE +SINGLE_ANIMATION(GougingFire); +#endif //P_FAMILY_GOUGING_FIRE +#if P_FAMILY_RAGING_BOLT +SINGLE_ANIMATION(RagingBolt); +#endif //P_FAMILY_RAGING_BOLT +#if P_FAMILY_IRON_BOULDER +SINGLE_ANIMATION(IronBoulder); +#endif //P_FAMILY_IRON_BOULDER +#if P_FAMILY_IRON_CROWN +SINGLE_ANIMATION(IronCrown); +#endif //P_FAMILY_IRON_CROWN +#if P_FAMILY_TERAPAGOS +SINGLE_ANIMATION(TerapagosNormal); +SINGLE_ANIMATION(TerapagosTerastal); +SINGLE_ANIMATION(TerapagosStellar); +#endif //P_FAMILY_TERAPAGOS +#if P_FAMILY_PECHARUNT +SINGLE_ANIMATION(Pecharunt); +#endif //P_FAMILY_PECHARUNT SINGLE_ANIMATION(Egg); diff --git a/src/data/text/nature_names.h b/src/data/text/nature_names.h deleted file mode 100644 index 5cf2d8024ca3..000000000000 --- a/src/data/text/nature_names.h +++ /dev/null @@ -1,54 +0,0 @@ -static const u8 sHardyNatureName[] = _("Hardy"); -static const u8 sLonelyNatureName[] = _("Lonely"); -static const u8 sBraveNatureName[] = _("Brave"); -static const u8 sAdamantNatureName[] = _("Adamant"); -static const u8 sNaughtyNatureName[] = _("Naughty"); -static const u8 sBoldNatureName[] = _("Bold"); -static const u8 sDocileNatureName[] = _("Docile"); -static const u8 sRelaxedNatureName[] = _("Relaxed"); -static const u8 sImpishNatureName[] = _("Impish"); -static const u8 sLaxNatureName[] = _("Lax"); -static const u8 sTimidNatureName[] = _("Timid"); -static const u8 sHastyNatureName[] = _("Hasty"); -static const u8 sSeriousNatureName[] = _("Serious"); -static const u8 sJollyNatureName[] = _("Jolly"); -static const u8 sNaiveNatureName[] = _("Naive"); -static const u8 sModestNatureName[] = _("Modest"); -static const u8 sMildNatureName[] = _("Mild"); -static const u8 sQuietNatureName[] = _("Quiet"); -static const u8 sBashfulNatureName[] = _("Bashful"); -static const u8 sRashNatureName[] = _("Rash"); -static const u8 sCalmNatureName[] = _("Calm"); -static const u8 sGentleNatureName[] = _("Gentle"); -static const u8 sSassyNatureName[] = _("Sassy"); -static const u8 sCarefulNatureName[] = _("Careful"); -static const u8 sQuirkyNatureName[] = _("Quirky"); - -const u8 *const gNatureNamePointers[NUM_NATURES] = -{ - [NATURE_HARDY] = sHardyNatureName, - [NATURE_LONELY] = sLonelyNatureName, - [NATURE_BRAVE] = sBraveNatureName, - [NATURE_ADAMANT] = sAdamantNatureName, - [NATURE_NAUGHTY] = sNaughtyNatureName, - [NATURE_BOLD] = sBoldNatureName, - [NATURE_DOCILE] = sDocileNatureName, - [NATURE_RELAXED] = sRelaxedNatureName, - [NATURE_IMPISH] = sImpishNatureName, - [NATURE_LAX] = sLaxNatureName, - [NATURE_TIMID] = sTimidNatureName, - [NATURE_HASTY] = sHastyNatureName, - [NATURE_SERIOUS] = sSeriousNatureName, - [NATURE_JOLLY] = sJollyNatureName, - [NATURE_NAIVE] = sNaiveNatureName, - [NATURE_MODEST] = sModestNatureName, - [NATURE_MILD] = sMildNatureName, - [NATURE_QUIET] = sQuietNatureName, - [NATURE_BASHFUL] = sBashfulNatureName, - [NATURE_RASH] = sRashNatureName, - [NATURE_CALM] = sCalmNatureName, - [NATURE_GENTLE] = sGentleNatureName, - [NATURE_SASSY] = sSassyNatureName, - [NATURE_CAREFUL] = sCarefulNatureName, - [NATURE_QUIRKY] = sQuirkyNatureName, -}; diff --git a/src/daycare.c b/src/daycare.c index 31d2abe62e48..e8426b4c0062 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -250,10 +250,10 @@ void StoreSelectedPokemonInDaycare(void) StorePokemonInEmptyDaycareSlot(&gPlayerParty[monId], &gSaveBlock1Ptr->daycare); } -// Shifts the second daycare pokemon slot into the first slot. +// Shifts the second daycare Pokémon slot into the first slot. static void ShiftDaycareSlots(struct DayCare *daycare) { - // This condition is only satisfied when the player takes out the first pokemon from the daycare. + // This condition is only satisfied when the player takes out the first Pokémon from the daycare. if (GetBoxMonData(&daycare->mons[1].mon, MON_DATA_SPECIES) != SPECIES_NONE && GetBoxMonData(&daycare->mons[0].mon, MON_DATA_SPECIES) == SPECIES_NONE) { @@ -738,7 +738,7 @@ static void InheritAbility(struct Pokemon *egg, struct BoxPokemon *father, struc } } -// Counts the number of egg moves a pokemon learns and stores the moves in +// 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) { diff --git a/src/debug.c b/src/debug.c index a28af058633c..e6dcb50494fa 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1492,6 +1492,7 @@ static void DebugTask_HandleMenuInput_FlagsVars(u8 taskId) PlaySE(SE_SELECT); if ((func = sDebugMenu_Actions_Flags[input]) != NULL) { + Debug_RedrawListMenu(taskId); func(taskId); // Remove TRUE/FALSE window for functions that haven't been assigned flags @@ -1501,8 +1502,6 @@ static void DebugTask_HandleMenuInput_FlagsVars(u8 taskId) RemoveWindow(gTasks[taskId].tSubWindowId); Free(sDebugMenuListData); } - else - Debug_RedrawListMenu(taskId); } } else if (JOY_NEW(B_BUTTON)) diff --git a/src/field_effect.c b/src/field_effect.c index 294d13b01c95..8309e10b8e2f 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -259,7 +259,7 @@ static const u32 sHofMonitorBig_Gfx[] = INCBIN_U32("graphics/field_effects/pics/ static const u8 sHofMonitorSmall_Gfx[] = INCBIN_U8("graphics/field_effects/pics/hof_monitor_small.4bpp"); static const u16 sHofMonitor_Pal[16] = INCBIN_U16("graphics/field_effects/palettes/hof_monitor.gbapal"); -// Graphics for the lights streaking past your Pokemon when it uses a field move. +// Graphics for the lights streaking past your Pokémon when it uses a field move. static const u32 sFieldMoveStreaksOutdoors_Gfx[] = INCBIN_U32("graphics/field_effects/pics/field_move_streaks.4bpp"); static const u16 sFieldMoveStreaksOutdoors_Pal[16] = INCBIN_U16("graphics/field_effects/pics/field_move_streaks.gbapal"); static const u16 sFieldMoveStreaksOutdoors_Tilemap[320] = INCBIN_U16("graphics/field_effects/pics/field_move_streaks.bin"); diff --git a/src/field_message_box.c b/src/field_message_box.c index 55124e7dfc0d..b797e1d35331 100755 --- a/src/field_message_box.c +++ b/src/field_message_box.c @@ -84,7 +84,7 @@ bool8 ShowPokenavFieldMessage(const u8 *str) StringExpandPlaceholders(gStringVar4, str); CreateTask(Task_HidePokenavMessageWhenDone, 0); StartMatchCallFromScript(str); - sFieldMessageBoxMode = 2; + sFieldMessageBoxMode = FIELD_MESSAGE_BOX_NORMAL; return TRUE; } diff --git a/src/fldeff_misc.c b/src/fldeff_misc.c index c01e88b5122e..513cd13e762e 100644 --- a/src/fldeff_misc.c +++ b/src/fldeff_misc.c @@ -308,7 +308,7 @@ static const struct SpriteTemplate sSpriteTemplate_RecordMixLights = .callback = SpriteCallbackDummy, }; -// For accessing pokemon storage PC or the Hall of Fame PC +// For accessing Pokémon storage PC or the Hall of Fame PC void ComputerScreenOpenEffect(u16 increment, u16 unused, u8 priority) { CreateComputerScreenEffectTask(Task_ComputerScreenOpenEffect, increment, unused, priority); diff --git a/src/frontier_util.c b/src/frontier_util.c index 15f5385e83e0..0317f6e15d54 100644 --- a/src/frontier_util.c +++ b/src/frontier_util.c @@ -326,7 +326,7 @@ static const struct FrontierBrainMon sFrontierBrainsMons[][2][FRONTIER_PARTY_SIZ }, [FRONTIER_FACILITY_FACTORY] = { - // Because Factory's pokemon are random, this facility's Brain also uses random pokemon. + // Because Factory's Pokémon are random, this facility's Brain also uses random Pokémon. // What is interesting, this team is actually the one Steven uses in the multi tag battle alongside the player. { { @@ -1947,7 +1947,7 @@ static void AppendIfValid(u16 species, u16 heldItem, u16 hp, u8 lvlMode, u8 monL // gSpecialVar_Result is the level mode before and after calls to this function // gSpecialVar_0x8004 is used to store the return value instead (TRUE if there are insufficient eligible mons) -// The names of ineligible pokemon that have been caught are also buffered to print +// The names of ineligible Pokémon that have been caught are also buffered to print static void CheckPartyIneligibility(void) { u16 speciesArray[PARTY_SIZE]; diff --git a/src/graphics.c b/src/graphics.c index 9ec11a5b8dc6..c00bb2c767f4 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -689,7 +689,7 @@ const u8 gHealthboxElementsGfxTable[] = INCBIN_U8("graphics/battle_interface/hpb "graphics/battle_interface/misc_frameend.4bpp", "graphics/battle_interface/ball_display.4bpp", "graphics/battle_interface/ball_caught_indicator.4bpp", - "graphics/battle_interface/status2.4bpp", // these three duplicate sets of graphics are for the opponent/partner pokemon + "graphics/battle_interface/status2.4bpp", // these three duplicate sets of graphics are for the opponent/partner Pokémon "graphics/battle_interface/status3.4bpp", "graphics/battle_interface/status4.4bpp", "graphics/battle_interface/healthbox_doubles_frameend.4bpp", @@ -1279,7 +1279,7 @@ const u32 gDomeTourneyLineUp_Tilemap[] = INCBIN_U32("graphics/battle_frontier/to const u32 gDomeTourneyInfoCard_Gfx[] = INCBIN_U32("graphics/battle_frontier/tourney_info_card.4bpp.lz"); const u32 gDomeTourneyInfoCard_Tilemap[] = INCBIN_U32("graphics/battle_frontier/tourney_info_card_tilemap.bin.lz"); const u32 gDomeTourneyInfoCardBg_Tilemap[] = INCBIN_U32("graphics/battle_frontier/tourney_info_card_bg.bin.lz"); -const u32 gDomeTourneyTreeButtons_Gfx[] = INCBIN_U32("graphics/battle_frontier/tourney_buttons.4bpp.lz"); // exit/cancel and pokeball buttons +const u32 gDomeTourneyTreeButtons_Gfx[] = INCBIN_U32("graphics/battle_frontier/tourney_buttons.4bpp.lz"); // exit/cancel and Poké Ball buttons const u32 gDomeTourneyTree_Pal[] = INCBIN_U32("graphics/battle_frontier/tourney_tree.gbapal.lz"); const u32 gDomeTourneyTreeButtons_Pal[] = INCBIN_U32("graphics/battle_frontier/tourney_buttons.gbapal.lz"); const u32 gDomeTourneyMatchCardBg_Pal[] = INCBIN_U32("graphics/battle_frontier/tourney_match_card_bg.gbapal.lz"); @@ -1731,7 +1731,7 @@ const u16 gFrontierPassMapCursor_Pal[] = INCBIN_U16("graphics/frontier_pass/map_ const u16 gFrontierPassMedalsSilver_Pal[] = INCBIN_U16("graphics/frontier_pass/silver.gbapal"); const u16 gFrontierPassMedalsGold_Pal[] = INCBIN_U16("graphics/frontier_pass/gold.gbapal"); -// Pokedex +// Pokédex const u16 gPokedexBgHoenn_Pal[] = INCBIN_U16("graphics/pokedex/bg_hoenn.gbapal"); const u16 gPokedexCaughtScreen_Pal[] = INCBIN_U16("graphics/pokedex/caught_screen.gbapal"); const u16 gPokedexSearchResults_Pal[] = INCBIN_U16("graphics/pokedex/search_results_bg.gbapal"); @@ -1785,7 +1785,7 @@ const u16 gContestResultsTitle_Smart_Tilemap[] = INCBIN_U16("graphics/contest/r const u16 gContestResultsTitle_Tough_Tilemap[] = INCBIN_U16("graphics/contest/results_screen/title_tough.bin"); const u16 gContestResultsTitle_Tilemap[] = INCBIN_U16("graphics/contest/results_screen/title.bin"); -// pokenav +// PokéNav const u16 gPokenavCondition_Pal[] = INCBIN_U16("graphics/pokenav/condition/graph.gbapal"); const u32 gPokenavCondition_Gfx[] = INCBIN_U32("graphics/pokenav/condition/graph.4bpp.lz"); @@ -1886,7 +1886,7 @@ const u32 gKantoTrainerCardFront_Tilemap[] = INCBIN_U32("graphics/trainer_card/f const u32 gKantoTrainerCardBack_Tilemap[] = INCBIN_U32("graphics/trainer_card/frlg/back.bin.lz"); const u32 gKantoTrainerCardFrontLink_Tilemap[] = INCBIN_U32("graphics/trainer_card/frlg/front_link.bin.lz"); -// pokemon storage system +// Pokémon storage system const u32 gStorageSystemMenu_Gfx[] = INCBIN_U32("graphics/pokemon_storage/menu.4bpp.lz"); const u16 gStorageSystemPartyMenu_Pal[] = INCBIN_U16("graphics/pokemon_storage/party_menu.gbapal"); diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c index cdb1edb4618b..f7a5d2c37899 100644 --- a/src/hall_of_fame.c +++ b/src/hall_of_fame.c @@ -625,7 +625,7 @@ static void Task_Hof_TryDisplayAnotherMon(u8 taskId) else { sHofFadePalettes |= (0x10000 << gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.paletteNum); - if (gTasks[taskId].tDisplayedMonId < PARTY_SIZE - 1 && currMon[1].species != SPECIES_NONE) // there is another pokemon to display + if (gTasks[taskId].tDisplayedMonId < PARTY_SIZE - 1 && currMon[1].species != SPECIES_NONE) // there is another Pokémon to display { gTasks[taskId].tDisplayedMonId++; BeginNormalPaletteFade(sHofFadePalettes, 0, 12, 12, RGB(16, 29, 24)); diff --git a/src/lottery_corner.c b/src/lottery_corner.c index d06934ca511f..4e58c2285808 100644 --- a/src/lottery_corner.c +++ b/src/lottery_corner.c @@ -73,7 +73,7 @@ void PickLotteryCornerTicket(void) } } } - else // pokemon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list. + else // Pokémon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list. break; } diff --git a/src/main.c b/src/main.c index 537af7191b02..b7d10cabcd79 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,7 @@ #include "intro.h" #include "main.h" #include "trainer_hill.h" +#include "test_runner.h" #include "constants/rgb.h" static void VBlankIntr(void); @@ -92,11 +93,6 @@ void EnableVCountIntrAtLine150(void); void AgbMain() { - // Modern compilers are liberal with the stack on entry to this function, - // so RegisterRamReset may crash if it resets IWRAM. -#if !MODERN - RegisterRamReset(RESET_ALL); -#endif //MODERN *(vu16 *)BG_PLTT = RGB_WHITE; // Set the backdrop to white on startup InitGpuRegManager(); REG_WAITCNT = WAITCNT_PREFETCH_ENABLE | WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3; @@ -372,7 +368,7 @@ static void VBlankIntr(void) m4aSoundMain(); TryReceiveLinkBattleData(); - if (!gMain.inBattle || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED))) + if (!gTestRunnerEnabled && (!gMain.inBattle || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED)))) AdvanceRandom(); UpdateWirelessStatusIndicatorSprite(); diff --git a/src/move_relearner.c b/src/move_relearner.c index af4593e53331..975663e4d3d2 100644 --- a/src/move_relearner.c +++ b/src/move_relearner.c @@ -369,7 +369,7 @@ static void VBlankCB_MoveRelearner(void) TransferPlttBuffer(); } -// Script arguments: The pokemon to teach is in VAR_0x8004 +// Script arguments: The Pokémon to teach is in VAR_0x8004 void TeachMoveRelearnerMove(void) { LockPlayerFieldControls(); diff --git a/src/overworld.c b/src/overworld.c index 09e242b21796..e18ae583c416 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -414,6 +414,8 @@ void Overworld_ResetStateAfterDigEscRope(void) FlagClear(B_SMART_WILD_AI_FLAG); FlagClear(B_FLAG_NO_BAG_USE); FlagClear(B_FLAG_NO_CATCHING); + FlagClear(B_FLAG_DYNAMAX_BATTLE); + FlagClear(B_FLAG_SKY_BATTLE); } #endif @@ -1325,7 +1327,7 @@ void UpdateAmbientCry(s16 *state, u16 *delayCounter) } } // Ambient cries after the first one take between 1200-2399 frames (~20-40 seconds) - // If the player has a pokemon with the ability Swarm in their party, the time is halved to 600-1199 frames (~10-20 seconds) + // If the player has a Pokémon with the ability Swarm in their party, the time is halved to 600-1199 frames (~10-20 seconds) *delayCounter = ((Random() % 1200) + 1200) / divBy; *state = AMB_CRY_WAIT; break; @@ -1337,7 +1339,7 @@ void UpdateAmbientCry(s16 *state, u16 *delayCounter) } break; case AMB_CRY_IDLE: - // No land/water pokemon on this map + // No land/water Pokémon on this map break; } } @@ -1348,7 +1350,7 @@ static void ChooseAmbientCrySpecies(void) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE130)) && !IsMirageIslandPresent()) { - // Only play water pokemon cries on this route + // Only play water Pokémon cries on this route // when Mirage Island is not present sIsAmbientCryWaterMon = TRUE; sAmbientCrySpecies = GetLocalWaterMon(); diff --git a/src/party_menu.c b/src/party_menu.c index e5d59e26a8af..6223e046b09a 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -180,7 +180,7 @@ enum { }; enum { - // Window ids 0-5 are implicitly assigned to each party pokemon in InitPartyMenuBoxes + // Window ids 0-5 are implicitly assigned to each party Pokémon in InitPartyMenuBoxes WIN_MSG = PARTY_SIZE, }; @@ -7108,7 +7108,7 @@ static bool8 TrySwitchInPokemon(void) u8 newSlot; u8 i; - // In a multi battle, slots 1, 4, and 5 are the partner's pokemon + // In a multi battle, slots 1, 4, and 5 are the partner's Pokémon if (IsMultiBattle() == TRUE && (slot == 1 || slot == 4 || slot == 5)) { StringCopy(gStringVar1, GetTrainerPartnerName()); diff --git a/src/pokeball.c b/src/pokeball.c index 0ed34b48ad11..89568215e947 100644 --- a/src/pokeball.c +++ b/src/pokeball.c @@ -1204,10 +1204,10 @@ static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 spritePalNum, u return LaunchBallFadeMonTask(unFadeLater, spritePalNum, selectedPalettes, BALL_POKE); } -// Sprite data for the pokemon +// Sprite data for the Pokémon #define sSpecies data[7] -// Sprite data for the pokeball +// Sprite data for the Poké Ball #define sMonSpriteId data[0] #define sDelay data[1] #define sMonPalNum data[2] @@ -1217,7 +1217,7 @@ static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 spritePalNum, u #define sFinalMonY data[6] #define sTrigIdx data[7] -// Pokeball in Birch intro, and when receiving via trade +// Poké Ball in Birch intro, and when receiving via trade void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 monPalNum, u8 x, u8 y, u8 oamPriority, u8 subpriority, u8 delay, u32 fadePalettes, u16 species) { u8 spriteId; diff --git a/src/pokedex.c b/src/pokedex.c index ee3656da6861..a0f53d97c071 100644 --- a/src/pokedex.c +++ b/src/pokedex.c @@ -1765,7 +1765,7 @@ static void Task_HandlePokedexStartMenuInput(u8 taskId) CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE); gMain.newKeys |= START_BUTTON; //Exit menu break; - case 3: //CLOSE POKEDEX + case 3: //CLOSE POKéDEX BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gTasks[taskId].func = Task_ClosePokedex; PlaySE(SE_PC_OFF); @@ -1965,12 +1965,12 @@ static void Task_HandleSearchResultsStartMenuInput(u8 taskId) CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE); gMain.newKeys |= START_BUTTON; break; - case 3: //BACK TO POKEDEX + case 3: //BACK TO POKéDEX BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gTasks[taskId].func = Task_ReturnToPokedexFromSearchResults; PlaySE(SE_TRUCK_DOOR); break; - case 4: //CLOSE POKEDEX + case 4: //CLOSE POKéDEX BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gTasks[taskId].func = Task_ClosePokedexFromSearchResultsStartMenu; PlaySE(SE_PC_OFF); @@ -2056,7 +2056,7 @@ static void Task_ClosePokedexFromSearchResultsStartMenu(u8 taskId) #undef tLoadScreenTaskId -// For loading main pokedex page or pokedex search results +// For loading main pokedex page or Pokédex search results static bool8 LoadPokedexListPage(u8 page) { switch (gMain.state) diff --git a/src/pokemon.c b/src/pokemon.c index a2e357f13416..96811a92dd24 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -362,6 +362,35 @@ const struct SpindaSpot gSpindaSpotGraphics[] = #include "data/pokemon/item_effects.h" +const u8 *const gNatureNamePointers[NUM_NATURES] = +{ + [NATURE_HARDY] = COMPOUND_STRING("Hardy"), + [NATURE_LONELY] = COMPOUND_STRING("Lonely"), + [NATURE_BRAVE] = COMPOUND_STRING("Brave"), + [NATURE_ADAMANT] = COMPOUND_STRING("Adamant"), + [NATURE_NAUGHTY] = COMPOUND_STRING("Naughty"), + [NATURE_BOLD] = COMPOUND_STRING("Bold"), + [NATURE_DOCILE] = COMPOUND_STRING("Docile"), + [NATURE_RELAXED] = COMPOUND_STRING("Relaxed"), + [NATURE_IMPISH] = COMPOUND_STRING("Impish"), + [NATURE_LAX] = COMPOUND_STRING("Lax"), + [NATURE_TIMID] = COMPOUND_STRING("Timid"), + [NATURE_HASTY] = COMPOUND_STRING("Hasty"), + [NATURE_SERIOUS] = COMPOUND_STRING("Serious"), + [NATURE_JOLLY] = COMPOUND_STRING("Jolly"), + [NATURE_NAIVE] = COMPOUND_STRING("Naive"), + [NATURE_MODEST] = COMPOUND_STRING("Modest"), + [NATURE_MILD] = COMPOUND_STRING("Mild"), + [NATURE_QUIET] = COMPOUND_STRING("Quiet"), + [NATURE_BASHFUL] = COMPOUND_STRING("Bashful"), + [NATURE_RASH] = COMPOUND_STRING("Rash"), + [NATURE_CALM] = COMPOUND_STRING("Calm"), + [NATURE_GENTLE] = COMPOUND_STRING("Gentle"), + [NATURE_SASSY] = COMPOUND_STRING("Sassy"), + [NATURE_CAREFUL] = COMPOUND_STRING("Careful"), + [NATURE_QUIRKY] = COMPOUND_STRING("Quirky"), +}; + const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] = { // Attack Defense Speed Sp.Atk Sp. Def [NATURE_HARDY] = { 0, 0, 0, 0, 0 }, diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index 95a8387066ca..645ba149e608 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -201,7 +201,7 @@ enum { CURSOR_AREA_IN_BOX, CURSOR_AREA_IN_PARTY, CURSOR_AREA_BOX_TITLE, - CURSOR_AREA_BUTTONS, // Party Pokemon and Close Box + CURSOR_AREA_BUTTONS, // Party Pokémon and Close Box }; #define CURSOR_AREA_IN_HAND CURSOR_AREA_BOX_TITLE // Alt name for cursor area used by Move Items diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index a9a70f127914..b6a64c0211db 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -91,13 +91,13 @@ enum { #define PSS_LABEL_WINDOW_PORTRAIT_SPECIES 19 // The lower name #define PSS_LABEL_WINDOW_END 20 -// Dynamic fields for the Pokemon Info page +// Dynamic fields for the Pokémon Info page #define PSS_DATA_WINDOW_INFO_ORIGINAL_TRAINER 0 #define PSS_DATA_WINDOW_INFO_ID 1 #define PSS_DATA_WINDOW_INFO_ABILITY 2 #define PSS_DATA_WINDOW_INFO_MEMO 3 -// Dynamic fields for the Pokemon Skills page +// Dynamic fields for the Pokémon Skills page #define PSS_DATA_WINDOW_SKILLS_HELD_ITEM 0 #define PSS_DATA_WINDOW_SKILLS_RIBBON_COUNT 1 #define PSS_DATA_WINDOW_SKILLS_STATS_LEFT 2 // HP, Attack, Defense @@ -180,7 +180,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData u8 currPageIndex; u8 minPageIndex; u8 maxPageIndex; - bool8 lockMonFlag; // This is used to prevent the player from changing pokemon in the move deleter select, etc, but it is not needed because the input is handled differently there + bool8 lockMonFlag; // This is used to prevent the player from changing Pokémon in the move deleter select, etc, but it is not needed because the input is handled differently there u16 newMove; u8 firstMoveIndex; u8 secondMoveIndex; @@ -190,7 +190,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData u8 windowIds[8]; u8 spriteIds[SPRITE_ARR_ID_COUNT]; bool8 handleDeoxys; - s16 switchCounter; // Used for various switch statement cases that decompress/load graphics or pokemon data + s16 switchCounter; // Used for various switch statement cases that decompress/load graphics or Pokémon data u8 unk_filler4[6]; u8 categoryIconSpriteId; } *sMonSummaryScreen = NULL; @@ -322,7 +322,6 @@ static void SummaryScreen_DestroyAnimDelayTask(void); // const rom data #include "data/text/move_descriptions.h" -#include "data/text/nature_names.h" static const struct BgTemplate sBgTemplates[] = { @@ -2795,7 +2794,7 @@ static void DrawContestMoveHearts(u16 move) } } -static void LimitEggSummaryPageDisplay(void) // If the pokemon is an egg, limit the number of pages displayed to 1 +static void LimitEggSummaryPageDisplay(void) // If the Pokémon is an egg, limit the number of pages displayed to 1 { if (sMonSummaryScreen->summary.isEgg) ChangeBgX(3, 0x10000, BG_COORD_SET); @@ -2841,7 +2840,7 @@ static void PrintNotEggInfo(void) if (dexNum != 0xFFFF) { - u8 digitCount = (NATIONAL_DEX_COUNT > 999 && IsNationalPokedexEnabled()) ? 4 : 3; + u8 digitCount = (NATIONAL_DEX_COUNT > 999 && IsNationalPokedexEnabled()) ? 4 : 3; StringCopy(gStringVar1, &gText_NumberClear01[0]); ConvertIntToDecimalStringN(gStringVar2, dexNum, STR_CONV_MODE_LEADING_ZEROS, digitCount); StringAppend(gStringVar1, gStringVar2); @@ -3958,10 +3957,7 @@ static void SetMoveTypeIcons(void) { if (summary->moves[i] != MOVE_NONE) { - if (summary->moves[i] == MOVE_IVY_CUDGEL && ItemId_GetHoldEffect(summary->item) == HOLD_EFFECT_MASK) - SetTypeSpritePosAndPal(ItemId_GetSecondaryId(summary->item), 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); - else - SetTypeSpritePosAndPal(gBattleMoves[summary->moves[i]].type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); + SetTypeSpritePosAndPal(gBattleMoves[summary->moves[i]].type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); } else SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE); @@ -4125,7 +4121,7 @@ static bool32 UNUSED IsMonAnimationFinished(void) return TRUE; } -static void StopPokemonAnimations(void) // A subtle effect, this function stops pokemon animations when leaving the PSS +static void StopPokemonAnimations(void) // A subtle effect, this function stops Pokémon animations when leaving the PSS { u16 i; u16 paletteIndex; diff --git a/src/pokenav_menu_handler.c b/src/pokenav_menu_handler.c index b81b4c892f63..d67f61c1ea46 100644 --- a/src/pokenav_menu_handler.c +++ b/src/pokenav_menu_handler.c @@ -257,7 +257,7 @@ static u32 HandleMainMenuInput(struct Pokenav_Menu *menu) return POKENAV_MENU_FUNC_NONE; } -// Force the player to select Match Call during the call Mr. Stone pokenav tutorial +// Force the player to select Match Call during the call Mr. Stone PokéNav tutorial static u32 HandleMainMenuInputTutorial(struct Pokenav_Menu *menu) { if (UpdateMenuCursorPos(menu)) @@ -287,7 +287,7 @@ static u32 HandleMainMenuInputTutorial(struct Pokenav_Menu *menu) return POKENAV_MENU_FUNC_NONE; } -// After calling Mr. Stone during the pokenav tutorial, force player to exit or use Match Call again +// After calling Mr. Stone during the PokéNav tutorial, force player to exit or use Match Call again static u32 HandleMainMenuInputEndTutorial(struct Pokenav_Menu *menu) { if (UpdateMenuCursorPos(menu)) diff --git a/src/reload_save.c b/src/reload_save.c index 5425d1c7c46d..f6104c1db76f 100644 --- a/src/reload_save.c +++ b/src/reload_save.c @@ -1,5 +1,6 @@ #include "global.h" #include "main.h" +#include "crt0.h" #include "gpu_regs.h" #include "m4a.h" #include "load_save.h" @@ -15,6 +16,7 @@ void ReloadSave(void) u16 imeBackup = REG_IME; REG_IME = 0; RegisterRamReset(RESET_EWRAM); + ReInitializeEWRAM(); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK); REG_IME = imeBackup; gMain.inBattle = FALSE; diff --git a/src/rom_header_gf.c b/src/rom_header_gf.c index 022eb9501740..4ded1a7ff353 100644 --- a/src/rom_header_gf.c +++ b/src/rom_header_gf.c @@ -8,7 +8,7 @@ // 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. -// In vanilla, it was used by Colosseum and XD to access pokemon graphics. +// In vanilla, it was used by Colosseum and XD to access Pokémon graphics. // // If this struct is rearranged in any way, it defeats the purpose of // having it at all. Applications like PKHex or streaming HUDs may find diff --git a/src/roulette.c b/src/roulette.c index 44dac2db6caf..ec4c8cfcfeb3 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -990,8 +990,8 @@ static const struct RouletteFlashSettings sFlashData_Colors[NUM_ROULETTE_SLOTS + }, }; -// Data to flash any pokemon icon (F_FLASH_ICON) on the roulette wheel. One entry for each color row -// Each poke icon flashes with the tint of the row color it belongs to, so the pokemon itself is irrelevant +// Data to flash any Pokémon icon (F_FLASH_ICON) on the roulette wheel. One entry for each color row +// Each poke icon flashes with the tint of the row color it belongs to, so the Pokémon itself is irrelevant static const struct RouletteFlashSettings sFlashData_PokeIcons[NUM_BOARD_COLORS] = { [GET_ROW_IDX(ROW_ORANGE)] = { @@ -2702,7 +2702,7 @@ static const struct SpriteTemplate sSpriteTemplates_GridIcons[NUM_BOARD_POKES] = } }; -// Wheel icons are listed clockwise starting from 1 oclock on the roulette wheel (with pokeball upside right) +// Wheel icons are listed clockwise starting from 1 oclock on the roulette wheel (with Poké Ball upside right) // They go Wynaut -> Azurill -> Skitty -> Makuhita, and Orange -> Green -> Purple static const struct SpriteTemplate sSpriteTemplates_WheelIcons[NUM_ROULETTE_SLOTS] = { @@ -4481,7 +4481,7 @@ static void SetBallStuck(struct Sprite *sprite) // The below slot ids are relative to the slot the ball got stuck on if ((sRoulette->useTaillow + 1) & sRoulette->partySpeciesFlags) { - // If the player has the corresponding pokemon in their party (HAS_SHROOMISH or HAS_TAILLOW), + // If the player has the corresponding Pokémon in their party (HAS_SHROOMISH or HAS_TAILLOW), // there's a 75% chance that the ball will be moved to a spot they bet on // assuming it was one of the slots identified as a candidate if (betSlotId && (rand % 256) < 192) diff --git a/src/save_location.c b/src/save_location.c index 74d2f2c44d0f..33842005980d 100644 --- a/src/save_location.c +++ b/src/save_location.c @@ -119,9 +119,9 @@ void TrySetMapSaveWarpStatus(void) TrySetUnknownWarpStatus(); } -// In FRLG, only bits 0, 4, and 5 are set when the pokedex is received. +// In FRLG, only bits 0, 4, and 5 are set when the Pokédex is received. // Bits 1, 2, 3, and 15 are instead set by SetPostgameFlags. -// These flags are read by Pokemon Colosseum/XD for linking. XD Additionally requires FLAG_SYS_GAME_CLEAR +// These flags are read by Pokémon Colosseum/XD for linking. XD Additionally requires FLAG_SYS_GAME_CLEAR void SetUnlockedPokedexFlags(void) { gSaveBlock2Ptr->gcnLinkFlags |= (1 << 15); diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index 04448b6f6ce0..2f3c29f2a747 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -256,7 +256,7 @@ void ReducePlayerPartyToSelectedMons(void) CpuFill32(0, party, sizeof party); - // copy the selected pokemon according to the order. + // copy the selected Pokémon according to the order. for (i = 0; i < MAX_FRONTIER_PARTY_SIZE; i++) if (gSelectedOrderFromParty[i]) // as long as the order keeps going (did the player select 1 mon? 2? 3?), do not stop party[i] = gPlayerParty[gSelectedOrderFromParty[i] - 1]; // index is 0 based, not literal diff --git a/src/start_menu.c b/src/start_menu.c index 9ef6adaf05a2..0525ccf70d7c 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -716,7 +716,7 @@ static bool8 StartMenuPokeNavCallback(void) PlayRainStoppingSoundEffect(); RemoveExtraStartMenuWindows(); CleanupOverworldWindowsAndTilemaps(); - SetMainCallback2(CB2_InitPokeNav); // Display PokeNav + SetMainCallback2(CB2_InitPokeNav); // Display PokéNav return TRUE; } @@ -1421,7 +1421,7 @@ static void ShowSaveInfoWindow(void) if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE) { - // Print pokedex count + // Print Pokédex count yOffset += 16; AddTextPrinterParameterized(sSaveInfoWindowId, FONT_NORMAL, gText_SavingPokedex, 0, yOffset, TEXT_SKIP_DRAW, NULL); BufferSaveMenuText(SAVE_MENU_CAUGHT, gStringVar4, color); diff --git a/src/starter_choose.c b/src/starter_choose.c index f1821fe04dd6..01b6600053da 100644 --- a/src/starter_choose.c +++ b/src/starter_choose.c @@ -26,7 +26,7 @@ #define STARTER_MON_COUNT 3 -// Position of the sprite of the selected starter Pokemon +// Position of the sprite of the selected starter Pokémon #define STARTER_PKMN_POS_X (DISPLAY_WIDTH / 2) #define STARTER_PKMN_POS_Y 64 @@ -446,7 +446,7 @@ void CB2_ChooseStarter(void) spriteId = CreateSprite(&sSpriteTemplate_Hand, 120, 56, 2); gSprites[spriteId].data[0] = taskId; - // Create three Pokeball sprites + // Create three Poké Ball sprites spriteId = CreateSprite(&sSpriteTemplate_Pokeball, sPokeballCoords[0][0], sPokeballCoords[0][1], 2); gSprites[spriteId].sTaskId = taskId; gSprites[spriteId].sBallId = 0; @@ -495,7 +495,7 @@ static void Task_HandleStarterChooseInput(u8 taskId) spriteId = CreateSprite(&sSpriteTemplate_StarterCircle, sPokeballCoords[selection][0], sPokeballCoords[selection][1], 1); gTasks[taskId].tCircleSpriteId = spriteId; - // Create Pokemon sprite + // Create Pokémon sprite spriteId = CreatePokemonFrontSprite(GetStarterPokemon(gTasks[taskId].tStarterSelection), sPokeballCoords[selection][0], sPokeballCoords[selection][1]); gSprites[spriteId].affineAnims = &sAffineAnims_StarterPokemon; gSprites[spriteId].callback = SpriteCB_StarterPokemon; @@ -637,7 +637,7 @@ static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y) static void SpriteCB_SelectionHand(struct Sprite *sprite) { - // Float up and down above selected pokeball + // Float up and down above selected Poké Ball sprite->x = sCursorCoords[gTasks[sprite->data[0]].tStarterSelection][0]; sprite->y = sCursorCoords[gTasks[sprite->data[0]].tStarterSelection][1]; sprite->y2 = Sin(sprite->data[1], 8); @@ -646,7 +646,7 @@ static void SpriteCB_SelectionHand(struct Sprite *sprite) static void SpriteCB_Pokeball(struct Sprite *sprite) { - // Animate pokeball if currently selected + // Animate Poké Ball if currently selected if (gTasks[sprite->sTaskId].tStarterSelection == sprite->sBallId) StartSpriteAnimIfDifferent(sprite, 1); else diff --git a/src/title_screen.c b/src/title_screen.c index 12015b8bd8aa..1d605d1fc056 100644 --- a/src/title_screen.c +++ b/src/title_screen.c @@ -680,7 +680,7 @@ static void MainCB2(void) UpdatePaletteFade(); } -// Shine the Pokemon logo two more times, and fade in the version banner +// Shine the Pokémon logo two more times, and fade in the version banner static void Task_TitleScreenPhase1(u8 taskId) { // Skip to next phase when A, B, Start, or Select is pressed @@ -728,7 +728,7 @@ static void Task_TitleScreenPhase1(u8 taskId) #undef sParentTaskId #undef sAlphaBlendIdx -// Create "Press Start" and copyright banners, and slide Pokemon logo up +// Create "Press Start" and copyright banners, and slide Pokémon logo up static void Task_TitleScreenPhase2(u8 taskId) { u32 yPos; @@ -767,7 +767,7 @@ static void Task_TitleScreenPhase2(u8 taskId) if (!(gTasks[taskId].tCounter & 1) && gTasks[taskId].tBg2Y != 0) gTasks[taskId].tBg2Y++; - // Slide Pokemon logo up + // Slide Pokémon logo up yPos = gTasks[taskId].tBg2Y * 256; SetGpuReg(REG_OFFSET_BG2Y_L, yPos); SetGpuReg(REG_OFFSET_BG2Y_H, yPos / 0x10000); diff --git a/src/trade.c b/src/trade.c index 0d7765857f44..080bd74f6615 100644 --- a/src/trade.c +++ b/src/trade.c @@ -168,7 +168,7 @@ static EWRAM_DATA u8 *sMenuTextTileBuffer = NULL; // Bytes 0-2 are used for the player's name text // Bytes 3-5 are used for the partner's name text // Bytes 6-7 are used for the Cancel text -// Bytes 8-13 are used for the Choose a Pokemon text +// Bytes 8-13 are used for the Choose a Pokémon text // See the corresponding GFXTAGs in src/data/trade.h static EWRAM_DATA u8 *sMenuTextTileBuffers[NUM_MENU_TEXT_SPRITES] = {NULL}; @@ -1006,25 +1006,25 @@ static void SetActiveMenuOptions(void) { if (i < sTradeMenu->partyCounts[TRADE_PLAYER]) { - // Present player pokemon + // Present player Pokémon gSprites[sTradeMenu->partySpriteIds[TRADE_PLAYER][i]].invisible = FALSE; sTradeMenu->optionsActive[i] = TRUE; } else { - // Absent player pokemon + // Absent player Pokémon sTradeMenu->optionsActive[i] = FALSE; } if (i < sTradeMenu->partyCounts[TRADE_PARTNER]) { - // Present partner pokemon + // Present partner Pokémon gSprites[sTradeMenu->partySpriteIds[TRADE_PARTNER][i]].invisible = FALSE; sTradeMenu->optionsActive[i + PARTY_SIZE] = TRUE; } else { - // Absent partner pokemon + // Absent partner Pokémon sTradeMenu->optionsActive[i + PARTY_SIZE] = FALSE; } } @@ -1281,7 +1281,7 @@ static void Leader_HandleCommunication(void) if (sTradeMenu->playerSelectStatus == STATUS_READY && sTradeMenu->partnerSelectStatus == STATUS_READY) { - // Both players have selected a pokemon to trade + // Both players have selected a Pokémon to trade sTradeMenu->callbackId = CB_SET_SELECTED_MONS; sTradeMenu->linkData[0] = LINKCMD_SET_MONS_TO_TRADE; sTradeMenu->linkData[1] = sTradeMenu->cursorPosition; @@ -1291,7 +1291,7 @@ static void Leader_HandleCommunication(void) else if (sTradeMenu->playerSelectStatus == STATUS_READY && sTradeMenu->partnerSelectStatus == STATUS_CANCEL) { - // The player has selected a pokemon to trade, + // The player has selected a Pokémon to trade, // but the partner has selected Cancel PrintTradeMessage(MSG_CANCELED); sTradeMenu->linkData[0] = LINKCMD_PARTNER_CANCEL_TRADE; @@ -1304,7 +1304,7 @@ static void Leader_HandleCommunication(void) else if (sTradeMenu->playerSelectStatus == STATUS_CANCEL && sTradeMenu->partnerSelectStatus == STATUS_READY) { - // The partner has selected a pokemon to trade, + // The partner has selected a Pokémon to trade, // but the player has selected cancel PrintTradeMessage(MSG_FRIEND_WANTS_TO_TRADE); sTradeMenu->linkData[0] = LINKCMD_PLAYER_CANCEL_TRADE; @@ -1461,7 +1461,7 @@ static void CB_ProcessMenuInput(void) if (sTradeMenu->cursorPosition < PARTY_SIZE) { - // Selected pokemon in player's party + // Selected Pokémon in player's party DrawTextBorderOuter(1, 1, 14); FillWindowPixelBuffer(1, PIXEL_FILL(1)); PrintMenuTable(1, ARRAY_COUNT(sSelectTradeMonActions), sSelectTradeMonActions); @@ -1472,7 +1472,7 @@ static void CB_ProcessMenuInput(void) } else if (sTradeMenu->cursorPosition < PARTY_SIZE * 2) { - // Selected pokemon in partner's party + // Selected Pokémon in partner's party BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); sTradeMenu->callbackId = CB_SHOW_MON_SUMMARY; } @@ -1848,7 +1848,7 @@ static void SetSelectedMon(u8 cursorPosition) if (sTradeMenu->drawSelectedMonState[whichParty] == 0) { // Start the animation to display just the selected - // pokemon in the middle of the screen + // Pokémon in the middle of the screen sTradeMenu->drawSelectedMonState[whichParty] = 1; sTradeMenu->selectedMonIdx[whichParty] = cursorPosition; } @@ -1882,10 +1882,10 @@ static void DrawSelectedMonScreen(u8 whichParty) for (i = 0; i < PARTY_SIZE; i++) ClearWindowTilemap(i + (whichParty * PARTY_SIZE + 2)); - // Re-display the selected pokemon + // Re-display the selected Pokémon gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].invisible = FALSE; - // Move the selected pokemon to the center + // Move the selected Pokémon to the center gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].data[0] = 20; gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].data[2] = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][0] + sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE + 1][0]) / 2 * 8 + 14; @@ -3088,13 +3088,13 @@ static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) struct Pokemon *partnerMon = &gEnemyParty[partnerPartyIdx]; u16 partnerMail = GetMonData(partnerMon, MON_DATA_MAIL); - // The mail attached to the sent Pokemon no longer exists in your file. + // The mail attached to the sent Pokémon no longer exists in your file. if (playerMail != MAIL_NONE) ClearMail(&gSaveBlock1Ptr->mail[playerMail]); SWAP(*playerMon, *partnerMon, sTradeAnim->tempMon); - // By default, a Pokemon received from a trade will have 70 Friendship. + // By default, a Pokémon received from a trade will have 70 Friendship. // Eggs use Friendship to track egg cycles, so don't set this on Eggs. friendship = 70; if (!GetMonData(playerMon, MON_DATA_IS_EGG)) diff --git a/src/trainer_pokemon_sprites.c b/src/trainer_pokemon_sprites.c index 0d1954ab71df..cfa013620a9e 100644 --- a/src/trainer_pokemon_sprites.c +++ b/src/trainer_pokemon_sprites.c @@ -11,7 +11,7 @@ #define PICS_COUNT 8 -// Needs to be large enough to store either a decompressed pokemon pic or trainer pic +// Needs to be large enough to store either a decompressed Pokémon pic or trainer pic #define PIC_SPRITE_SIZE max(MON_PIC_SIZE, TRAINER_PIC_SIZE) #define MAX_PIC_FRAMES max(MAX_MON_PIC_FRAMES, MAX_TRAINER_PIC_FRAMES) diff --git a/src/tv.c b/src/tv.c index 0211ef71e2cb..e89f6a9145cc 100644 --- a/src/tv.c +++ b/src/tv.c @@ -6206,7 +6206,7 @@ static void DoTVShowSpotTheCuties(void) TVShowConvertInternationalString(gStringVar1, show->cuties.playerName, show->cuties.language); TVShowConvertInternationalString(gStringVar2, show->cuties.nickname, show->cuties.pokemonNameLanguage); - // Comments following the intro depend on how many ribbons the pokemon has + // Comments following the intro depend on how many ribbons the Pokémon has if (show->cuties.nRibbons < 10) sTVShowState = SPOTCUTIES_STATE_RIBBONS_LOW; else if (show->cuties.nRibbons < 20) diff --git a/src/use_pokeblock.c b/src/use_pokeblock.c index 2aefdedf38e3..c9d5c56e5c04 100644 --- a/src/use_pokeblock.c +++ b/src/use_pokeblock.c @@ -73,10 +73,10 @@ struct UsePokeblockSession u8 natureText[34]; }; -// This struct is identical to PokenavMonListItem, the struct used for managing lists of pokemon in the pokenav +// This struct is identical to PokenavMonListItem, the struct used for managing lists of Pokémon in the PokéNav // Given that this screen is essentially duplicated in the poknav, this struct was probably the same one with // a more general name/purpose -// TODO: Once the pokenav conditions screens are documented, resolve the above +// TODO: Once the PokéNav conditions screens are documented, resolve the above struct UsePokeblockMenuPokemon { u8 boxId; // Because this screen is never used for the PC this is always set to TOTAL_BOXES_COUNT to refer to party @@ -1259,7 +1259,7 @@ static void LoadAndCreateSelectionIcons(void) LoadSpriteSheets(spriteSheets); LoadSpritePalettes(spritePals); - // Fill pokeball selection icons up to number in party + // Fill Poké Ball selection icons up to number in party for (i = 0; i < sMenu->info.numSelections - 1; i++) { spriteId = CreateSprite(&spriteTemplate, 226, (i * 20) + 8, 0); @@ -1489,7 +1489,7 @@ static bool8 LoadNewSelection_CancelToMon(void) case 2: if (!ConditionMenu_UpdateMonEnter(&sMenu->graph, &sMenu->curMonXOffset)) { - // Load the new adjacent pokemon (not the one being shown) + // Load the new adjacent Pokémon (not the one being shown) LoadMonInfo(sMenu->toLoadSelection, sMenu->toLoadId); sMenu->info.helperState++; } @@ -1552,7 +1552,7 @@ static bool8 LoadNewSelection_MonToMon(void) case 2: if (!ConditionMenu_UpdateMonEnter(&sMenu->graph, &sMenu->curMonXOffset)) { - // Load the new adjacent pokemon (not the one being shown) + // Load the new adjacent Pokémon (not the one being shown) LoadMonInfo(sMenu->toLoadSelection, sMenu->toLoadId); sMenu->info.helperState++; } @@ -1593,8 +1593,8 @@ static void SpriteCB_SelectionIconCancel(struct Sprite *sprite) sprite->oam.paletteNum = IndexOfSpritePaletteTag(TAG_CONDITION_CANCEL); } -// Calculate the max id for sparkles/stars that appear around the pokemon on the condition screen -// All pokemon start with 1 sparkle (added by CreateConditionSparkleSprites), so the number here +1 +// Calculate the max id for sparkles/stars that appear around the Pokémon on the condition screen +// All Pokémon start with 1 sparkle (added by CreateConditionSparkleSprites), so the number here +1 // is the total number of sparkles that appear static void CalculateNumAdditionalSparkles(u8 monIndex) { diff --git a/src/wild_encounter.c b/src/wild_encounter.c index f4412c479aca..474c5ef560fe 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -403,7 +403,7 @@ u8 PickWildMonNature(void) } } } - // check synchronize for a pokemon with the same ability + // check synchronize for a Pokémon with the same ability if (OW_SYNCHRONIZE_NATURE < GEN_9 && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG) && GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE @@ -902,16 +902,16 @@ u16 GetLocalWildMon(bool8 *isWaterMon) // Neither if (landMonsInfo == NULL && waterMonsInfo == NULL) return SPECIES_NONE; - // Land Pokemon + // Land Pokémon else if (landMonsInfo != NULL && waterMonsInfo == NULL) return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species; - // Water Pokemon + // Water Pokémon else if (landMonsInfo == NULL && waterMonsInfo != NULL) { *isWaterMon = TRUE; return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species; } - // Either land or water Pokemon + // Either land or water Pokémon if ((Random() % 100) < 80) { return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species; diff --git a/test/battle/ability/shields_down.c b/test/battle/ability/shields_down.c new file mode 100644 index 000000000000..d0149e13f99c --- /dev/null +++ b/test/battle/ability/shields_down.c @@ -0,0 +1,34 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Minior Meteor transforms into Minior Core on switch-in if it has 1/2 or less health") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_MINIOR_METEOR) { Ability(ABILITY_SHIELDS_DOWN); HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponent); + } THEN { + EXPECT_EQ(opponent->species, SPECIES_MINIOR_CORE); + } +} + +SINGLE_BATTLE_TEST("Minior Core transforms into Minior Meteor on switch-in if it more then 1/2 health") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_MINIOR_CORE) { Ability(ABILITY_SHIELDS_DOWN); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponent); + } THEN { + EXPECT_EQ(opponent->species, SPECIES_MINIOR_METEOR); + } +} diff --git a/test/battle/hold_effect/gems.c b/test/battle/hold_effect/gems.c index c98718313d7a..c4ef15a0f1d3 100644 --- a/test/battle/hold_effect/gems.c +++ b/test/battle/hold_effect/gems.c @@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("Gem boost is only applied once") s16 normalHit; GIVEN { - ASSUME(I_GEM_BOOST_POWER >= GEN_5); + ASSUME(I_GEM_BOOST_POWER >= GEN_6); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); }; OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/item_effect/escape.c b/test/battle/item_effect/escape.c new file mode 100644 index 000000000000..0947a4ff9a51 --- /dev/null +++ b/test/battle/item_effect/escape.c @@ -0,0 +1,50 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gItems[ITEM_POKE_TOY].battleUsage == EFFECT_ITEM_ESCAPE); +} + +WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { USE_ITEM(player, ITEM_POKE_TOY); } + } SCENE { + MESSAGE("{PLAY_SE SE_FLEE}Got away safely!\p"); + } +} + +WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle even if a move forbid them to") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_MEAN_LOOK].effect == EFFECT_MEAN_LOOK); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_MEAN_LOOK); } + TURN { USE_ITEM(player, ITEM_POKE_TOY); } + } SCENE { + // Turn 1 + MESSAGE("Wild Wobbuffet used Mean Look!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MEAN_LOOK, opponent); + MESSAGE("Wobbuffet can't escape now!"); + // Turn 2 + MESSAGE("{PLAY_SE SE_FLEE}Got away safely!\p"); + } +} + +WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle even if an ability forbid them to") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_DIGLETT) { Ability(ABILITY_ARENA_TRAP); } + } WHEN { + TURN { USE_ITEM(player, ITEM_POKE_TOY); } + } SCENE { + MESSAGE("{PLAY_SE SE_FLEE}Got away safely!\p"); + } +} diff --git a/test/battle/item_effect/restore_pp.c b/test/battle/item_effect/restore_pp.c index e998ef3d98cb..ef621ca0f243 100644 --- a/test/battle/item_effect/restore_pp.c +++ b/test/battle/item_effect/restore_pp.c @@ -64,3 +64,5 @@ SINGLE_BATTLE_TEST("Max Elixir restores the PP of all of a battler's moves fully EXPECT_EQ(player->pp[3], 40); } } + +TO_DO_BATTLE_TEST("Ether won't work if the selected move has all its PP") diff --git a/test/battle/item_effect/revive.c b/test/battle/item_effect/revive.c index 2be2ac4a61d9..45c57322e833 100644 --- a/test/battle/item_effect/revive.c +++ b/test/battle/item_effect/revive.c @@ -72,3 +72,5 @@ SINGLE_BATTLE_TEST("Max Honey restores a fainted battler's HP fully") EXPECT_EQ(player->hp, 200); } } + +TO_DO_BATTLE_TEST("Revive won't restore a battler's HP if it hasn't fainted") diff --git a/test/battle/item_effect/throw_ball.c b/test/battle/item_effect/throw_ball.c new file mode 100644 index 000000000000..17ba01db5091 --- /dev/null +++ b/test/battle/item_effect/throw_ball.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Poke Balls can't be thrown when there's 2 opposing wild battlers") +TO_DO_BATTLE_TEST("Poke Balls can't be thrown when there's no space in the Pokemon Storage System") +TO_DO_BATTLE_TEST("Poke Balls can't be thrown when an opposing wild battler is in a semi-invulnerable state") +TO_DO_BATTLE_TEST("Poke Balls can't be thrown when B_FLAG_NO_CATCHING is set") diff --git a/test/battle/move_effect/confusion_hit.c b/test/battle/move_effect/confusion_hit.c new file mode 100644 index 000000000000..45077f42d001 --- /dev/null +++ b/test/battle/move_effect/confusion_hit.c @@ -0,0 +1,50 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Alluring Voice confuses the target if the target raised a stat this turn") +{ + u16 move; + + PARAMETRIZE { move = MOVE_CELEBRATE; } + PARAMETRIZE { move = MOVE_SWORDS_DANCE; } + + GIVEN { + ASSUME(gBattleMoves[MOVE_ALLURING_VOICE].effect == EFFECT_CONFUSE_HIT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_ALLURING_VOICE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLURING_VOICE, player); + HP_BAR(opponent); + if (move == MOVE_SWORDS_DANCE) { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } else { + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } + } + } +} + +SINGLE_BATTLE_TEST("Alluring Voice confuse effect is removed if it is Sheer Force boosted") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_ALLURING_VOICE].effect == EFFECT_CONFUSE_HIT); + PLAYER(SPECIES_NIDOKING) { Ability(ABILITY_SHEER_FORCE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SWORDS_DANCE); MOVE(player, MOVE_ALLURING_VOICE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWORDS_DANCE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLURING_VOICE, player); + HP_BAR(opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent); + MESSAGE("Foe Wobbuffet became confused!"); + } + } +} diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c index 8a7144b4300f..23671b38463e 100644 --- a/test/battle/move_effect/doodle.c +++ b/test/battle/move_effect/doodle.c @@ -49,7 +49,7 @@ DOUBLE_BATTLE_TEST("Doodle can't copy a banned ability") DOUBLE_BATTLE_TEST("Doodle fails if user has a banned Ability") { GIVEN { - PLAYER(SPECIES_GREAT_TUSK) { Ability(ABILITY_PROTOSYNTHESIS); } + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); } OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } OPPONENT(SPECIES_WOBBUFFET); @@ -59,7 +59,7 @@ DOUBLE_BATTLE_TEST("Doodle fails if user has a banned Ability") ANIMATION(ANIM_TYPE_MOVE, MOVE_DOODLE, playerLeft); MESSAGE("But it failed!"); } THEN { - EXPECT(playerLeft->ability == ABILITY_PROTOSYNTHESIS); + EXPECT(playerLeft->ability == ABILITY_GULP_MISSILE); EXPECT(playerRight->ability == ABILITY_SHADOW_TAG); } } @@ -68,7 +68,7 @@ DOUBLE_BATTLE_TEST("Doodle fails if partner has a banned Ability") { GIVEN { PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); } - PLAYER(SPECIES_GREAT_TUSK) { Ability(ABILITY_PROTOSYNTHESIS); } + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -78,6 +78,6 @@ DOUBLE_BATTLE_TEST("Doodle fails if partner has a banned Ability") MESSAGE("But it failed!"); } THEN { EXPECT(playerLeft->ability == ABILITY_SHADOW_TAG); - EXPECT(playerRight->ability == ABILITY_PROTOSYNTHESIS); + EXPECT(playerRight->ability == ABILITY_GULP_MISSILE); } } diff --git a/test/battle/move_effect/fickle_beam.c b/test/battle/move_effect/fickle_beam.c new file mode 100644 index 000000000000..2732b641a6d6 --- /dev/null +++ b/test/battle/move_effect/fickle_beam.c @@ -0,0 +1,30 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_FICKLE_BEAM].effect == EFFECT_FICKLE_BEAM); +} + +SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time") +{ + s16 damage[2]; + + PASSES_RANDOMLY(30, 100, RNG_FICKLE_BEAM); + GIVEN { + ASSUME(gBattleMoves[MOVE_POWER_GEM].power == 80); + ASSUME(gBattleMoves[MOVE_FICKLE_BEAM].power == 80); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_POWER_GEM); } + TURN { MOVE(player, MOVE_FICKLE_BEAM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_GEM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FICKLE_BEAM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + } +} diff --git a/test/battle/move_effect/ivy_cudgel.c b/test/battle/move_effect/ivy_cudgel.c index 819047f34a74..47db28f50d36 100644 --- a/test/battle/move_effect/ivy_cudgel.c +++ b/test/battle/move_effect/ivy_cudgel.c @@ -3,22 +3,22 @@ ASSUMPTIONS { - ASSUME(gBattleMoves[MOVE_IVY_CUDGEL].effect == EFFECT_CHANGE_TYPE_ON_ITEM); - ASSUME(gBattleMoves[MOVE_IVY_CUDGEL].argument == HOLD_EFFECT_MASK); + ASSUME(gBattleMoves[MOVE_IVY_CUDGEL].effect == EFFECT_IVY_CUDGEL); } -SINGLE_BATTLE_TEST("Ivy Cudgel changes the move type depending on the mask the user holds") +SINGLE_BATTLE_TEST("Ivy Cudgel changes the move type depending on the form of Ogerpon") { u16 species; + u16 ogerpon; u16 item; - PARAMETRIZE { species = SPECIES_BLASTOISE; item = ITEM_NONE; } - PARAMETRIZE { species = SPECIES_CHARIZARD; item = ITEM_CORNERSTONE_MASK; } - PARAMETRIZE { species = SPECIES_CHARIZARD; item = ITEM_WELLSPRING_MASK; } - PARAMETRIZE { species = SPECIES_VENUSAUR; item = ITEM_HEARTHFLAME_MASK; } + PARAMETRIZE { species = SPECIES_BLASTOISE; ogerpon = SPECIES_OGERPON_TEAL_MASK; item = ITEM_NONE; } + PARAMETRIZE { species = SPECIES_CHARIZARD; ogerpon = SPECIES_OGERPON_CORNERSTONE_MASK; item = ITEM_CORNERSTONE_MASK; } + PARAMETRIZE { species = SPECIES_CHARIZARD; ogerpon = SPECIES_OGERPON_WELLSPRING_MASK; item = ITEM_WELLSPRING_MASK; } + PARAMETRIZE { species = SPECIES_VENUSAUR; ogerpon = SPECIES_OGERPON_HEARTHFLAME_MASK; item = ITEM_HEARTHFLAME_MASK; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Item(item); } + PLAYER(ogerpon) { Item(item); } OPPONENT(species); } WHEN { TURN { MOVE(player, MOVE_IVY_CUDGEL); } @@ -28,3 +28,24 @@ SINGLE_BATTLE_TEST("Ivy Cudgel changes the move type depending on the mask the u MESSAGE("It's super effective!"); } } + +SINGLE_BATTLE_TEST("Ivy Cudgel does not change the move type if used by Pokémon other than Ogerpon") +{ + u16 item; + + PARAMETRIZE { item = ITEM_NONE; } + PARAMETRIZE { item = ITEM_CORNERSTONE_MASK; } + PARAMETRIZE { item = ITEM_WELLSPRING_MASK; } + PARAMETRIZE { item = ITEM_HEARTHFLAME_MASK; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(item); } + OPPONENT(SPECIES_BLASTOISE); + } WHEN { + TURN { MOVE(player, MOVE_IVY_CUDGEL); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_IVY_CUDGEL, player); + HP_BAR(opponent); + MESSAGE("It's super effective!"); // Should be super effective everytime if type isnt being changed + } +} diff --git a/test/battle/move_effect/meteor_beam.c b/test/battle/move_effect/meteor_beam.c new file mode 100644 index 000000000000..600de153d47f --- /dev/null +++ b/test/battle/move_effect/meteor_beam.c @@ -0,0 +1,61 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_ELECTRO_SHOT].effect == EFFECT_METEOR_BEAM); +} + +SINGLE_BATTLE_TEST("Electro Shot needs a charging Turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRO_SHOT); } + TURN { SKIP_TURN(player); } + } SCENE { + // Charging turn + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + // Attack turn + MESSAGE("Wobbuffet used Electro Shot!"); + } +} + +SINGLE_BATTLE_TEST("Electro Shot doesn't need to charge when it's raining") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_RAIN_DANCE); MOVE(player, MOVE_ELECTRO_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAIN_DANCE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + MESSAGE("Wobbuffet used Electro Shot!"); + } +} + +SINGLE_BATTLE_TEST("Electro Shot doesn't need to charge with Power Herb") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POWER_HERB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRO_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRO_SHOT, player); + MESSAGE("Wobbuffet absorbed electricity!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Sp. Atk rose!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet became fully charged due to its Power Herb!"); + MESSAGE("Wobbuffet used Electro Shot!"); + } +} diff --git a/test/battle/move_effect/photon_geyser.c b/test/battle/move_effect/photon_geyser.c new file mode 100644 index 000000000000..4171264a1a4e --- /dev/null +++ b/test/battle/move_effect/photon_geyser.c @@ -0,0 +1,51 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_PHOTON_GEYSER].effect == EFFECT_PHOTON_GEYSER); +} + +SINGLE_BATTLE_TEST("Photon Geyser can be mirror coated if it is a special move") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Attack(100); SpAttack(110); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PHOTON_GEYSER); MOVE(opponent, MOVE_MIRROR_COAT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PHOTON_GEYSER, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, opponent); + HP_BAR(player); + } +} + +SINGLE_BATTLE_TEST("Photon Geyser can be countered if it is a physcal move") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Attack(110); SpAttack(100); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PHOTON_GEYSER); MOVE(opponent, MOVE_COUNTER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PHOTON_GEYSER, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_COUNTER, opponent); + HP_BAR(player); + } +} + +SINGLE_BATTLE_TEST("Photon Geyser ignores ignorable Abilities like Battle Armor") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_LAPRAS) { Ability(ABILITY_SHELL_ARMOR); } + } WHEN { + TURN { MOVE(player, MOVE_PHOTON_GEYSER, criticalHit: TRUE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PHOTON_GEYSER, player, ); + HP_BAR(opponent); + MESSAGE("A critical hit!"); + } +} diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 502eab46e012..c527a4881d0e 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -12,6 +12,7 @@ ASSUMPTIONS ASSUME(gBattleMoves[MOVE_QUICK_GUARD].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_CRAFTY_SHIELD].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_BANEFUL_BUNKER].effect == EFFECT_PROTECT); + ASSUME(gBattleMoves[MOVE_BURNING_BULWARK].effect == EFFECT_PROTECT); ASSUME(gBattleMoves[MOVE_TACKLE].category == BATTLE_CATEGORY_PHYSICAL); ASSUME(gBattleMoves[MOVE_TACKLE].makesContact); ASSUME(gBattleMoves[MOVE_LEER].category == BATTLE_CATEGORY_STATUS); @@ -19,7 +20,7 @@ ASSUMPTIONS ASSUME(!(gBattleMoves[MOVE_WATER_GUN].makesContact)); } -SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield and Baneful Bunker protect from all moves") +SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield, Baneful Bunker and Burning Bulwark protect from all moves") { u32 j; static const u16 protectMoves[] = { @@ -27,6 +28,7 @@ SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield and Baneful Bunker protect fro MOVE_DETECT, MOVE_SPIKY_SHIELD, MOVE_BANEFUL_BUNKER, + MOVE_BURNING_BULWARK, }; u16 protectMove = MOVE_NONE; u16 usedMove = MOVE_NONE; @@ -188,6 +190,38 @@ SINGLE_BATTLE_TEST("Baneful Bunker poisons pokemon for moves making contact") } } +SINGLE_BATTLE_TEST("Burning Bulwark burns pokemon for moves making contact") +{ + u16 usedMove = MOVE_NONE; + + PARAMETRIZE {usedMove = MOVE_TACKLE; } + PARAMETRIZE {usedMove = MOVE_LEER; } + PARAMETRIZE {usedMove = MOVE_WATER_GUN; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_BURNING_BULWARK); MOVE(player, usedMove); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURNING_BULWARK, opponent); + MESSAGE("Foe Wobbuffet protected itself!"); + NOT ANIMATION(ANIM_TYPE_MOVE, usedMove, player); + MESSAGE("Foe Wobbuffet protected itself!"); + if (usedMove == MOVE_TACKLE) { + NOT HP_BAR(opponent); + STATUS_ICON(player, STATUS1_BURN); + } else { + NONE_OF { + HP_BAR(opponent); + STATUS_ICON(player, STATUS1_BURN); + } + } + } +} + SINGLE_BATTLE_TEST("Recoil damage is not applied if target was protected") { u32 j, k; diff --git a/test/battle/move_effect/strength_sap.c b/test/battle/move_effect/strength_sap.c index c549e4c332cc..d8e0b6e74bb3 100644 --- a/test/battle/move_effect/strength_sap.c +++ b/test/battle/move_effect/strength_sap.c @@ -57,3 +57,142 @@ SINGLE_BATTLE_TEST("Strength Sap works exactly the same when attacker is behind EXPECT_EQ(results[i].hp * -1, atkStat); } } + +// This test checks all stat stages from -6 to +6. +SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on target's Attack Stat and stat Change", s16 hp) +{ + s32 j = 0, statStage = 0; + + for (j = 0; j <= MAX_STAT_STAGE; j++) { + if (j == DEFAULT_STAT_STAGE - 1) { continue; } // Ignore -6, because Strength Sap won't work otherwise + PARAMETRIZE{ statStage = j; } + } + + GIVEN { + ASSUME(gBattleMoves[MOVE_WORK_UP].effect == EFFECT_ATTACK_SPATK_UP); + ASSUME(gBattleMoves[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + PLAYER(SPECIES_WOBBUFFET) { HP(50); } + OPPONENT(SPECIES_WOBBUFFET) { Attack(60); } + } WHEN { + if (statStage > DEFAULT_STAT_STAGE) { // + + for (j = statStage; j > DEFAULT_STAT_STAGE; j--) { + TURN { MOVE(opponent, MOVE_HOWL); } + } + } else if (statStage < DEFAULT_STAT_STAGE) { // - + for (j = statStage; j < DEFAULT_STAT_STAGE - 1; j++) { // - 1 because Strength Sap always lowers Attack + TURN { MOVE(player, MOVE_GROWL); } + } + } + TURN { MOVE(player, MOVE_STRENGTH_SAP); } + } SCENE { + if (statStage > DEFAULT_STAT_STAGE) { // + + for (j = statStage; j > DEFAULT_STAT_STAGE; j--) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, opponent); + } + } else if (statStage < DEFAULT_STAT_STAGE) { // - + for (j = statStage; j < DEFAULT_STAT_STAGE - 1; j++) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWL, player); + } + } + MESSAGE("Wobbuffet used Strength Sap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Attack fell!"); + HP_BAR(player, captureDamage: &results[i].hp); + MESSAGE("Foe Wobbuffet had its energy drained!"); + } THEN { + if (statStage < DEFAULT_STAT_STAGE) { + EXPECT_EQ(results[i].hp * -1, (60 * gStatStageRatios[statStage + 1][0] / gStatStageRatios[statStage + 1][1])); + } else { + EXPECT_EQ(results[i].hp * -1, (60 * gStatStageRatios[statStage][0] / gStatStageRatios[statStage][1])); + } + } FINALLY { + // This makes sure gStatStageRatios works correctly and the lower the attack stage the lower hp obtained. + for (j = 0; j < MAX_STAT_STAGE - 1; j++) { + EXPECT_GT(abs(results[j + 1].hp), abs(results[j].hp)); + } + } +} + +SINGLE_BATTLE_TEST("Strength Sap fails if target is at -6 Atk") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CHARM); } + TURN { MOVE(player, MOVE_CHARM); } + TURN { MOVE(player, MOVE_CHARM); } + TURN { MOVE(player, MOVE_STRENGTH_SAP); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARM, player); + MESSAGE("Wobbuffet used Strength Sap!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Attack fell!"); + HP_BAR(player); + MESSAGE("Foe Wobbuffet had its energy drained!"); + } + MESSAGE("Foe Wobbuffet's Attack won't go lower!"); + } +} + +SINGLE_BATTLE_TEST("Strength Sap restores more HP if Big Root is held", s16 hp) +{ + u32 item; + + PARAMETRIZE { item = ITEM_NONE; } + PARAMETRIZE { item = ITEM_BIG_ROOT; } + + GIVEN { + ASSUME(gItems[ITEM_BIG_ROOT].holdEffect == HOLD_EFFECT_BIG_ROOT); + PLAYER(SPECIES_WOBBUFFET) { HP(200); Item(item); } + OPPONENT(SPECIES_WOBBUFFET) { Attack(100); } + } WHEN { + TURN { MOVE(player, MOVE_STRENGTH_SAP); } + } SCENE { + MESSAGE("Wobbuffet used Strength Sap!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Wobbuffet's Attack fell!"); + HP_BAR(player, captureDamage: &results[i].hp); + MESSAGE("Foe Wobbuffet had its energy drained!"); + } FINALLY { + 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("Foe Wobbuffet's Attack fell!"); + ABILITY_POPUP(opponent, ABILITY_LIQUID_OOZE); + HP_BAR(player, captureDamage: &lostHp); + MESSAGE("It sucked up the liquid ooze!"); + if (atkStat >= 490) { + MESSAGE("Wobbuffet fainted!"); + MESSAGE("Go! Wobbuffet!"); + } + } THEN { + EXPECT_EQ(lostHp, atkStat); + } +} diff --git a/test/test_runner.c b/test/test_runner.c index 577ea1dbc11f..72ce5cf665e8 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -106,6 +106,8 @@ static u32 AssignCostToRunner(void) void CB2_TestRunner(void) { +top: + switch (gTestRunnerState.state) { case STATE_INIT: @@ -361,6 +363,9 @@ void CB2_TestRunner(void) MgbaExit_(gTestRunnerState.exitCode); break; } + + if (gMain.callback2 == CB2_TestRunner) + goto top; } void Test_ExpectedResult(enum TestResult result) @@ -662,3 +667,25 @@ static s32 MgbaVPrintf_(const char *fmt, va_list va) } return i; } + +/* Entry point for the Debugging and Control System. Handles illegal + * instructions, which are typically caused by branching to an invalid + * address. */ +__attribute__((naked, section(".dacs"), target("arm"))) +void DACSEntry(void) +{ + asm(".arm\n\ + ldr r0, =(DACSHandle + 1)\n\ + bx r0\n"); +} + +#define DACS_LR (*(vu32 *)0x3007FEC) + +void DACSHandle(void) +{ + if (gTestRunnerState.state == STATE_RUN_TEST) + gTestRunnerState.state = STATE_REPORT_RESULT; + gTestRunnerState.result = TEST_RESULT_CRASH; + ReinitCallbacks(); + DACS_LR = ((uintptr_t)JumpToAgbMainLoop & ~1) + 4; +}