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..d89901522569 100644 --- a/Makefile +++ b/Makefile @@ -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 30b0ab0ee2dc..c7377378b768 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -980,7 +980,7 @@ .byte 0xbb .endm - .macro maxattackhalvehp failInstr:req + .macro halvehp failInstr:req .byte 0xbc .4byte \failInstr .endm @@ -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/asm/macros/event.inc b/asm/macros/event.inc index 89d3fa8072a9..f2af499b522c 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -2057,3 +2057,33 @@ callnative CreateTrainerPartyForPlayer trainerbattle_no_intro \trainer2, NULL .endm + + @ Sets VAR_RESULT to TRUE if stat can be hyper trained, or to + @ FALSE otherwise. + .macro canhypertrain stat:req, slot:req + callnative CanHyperTrain + .byte \stat + .2byte \slot + .endm + + @ Hyper Trains a stat. + .macro hypertrain stat:req, slot:req + callnative HyperTrain + .byte \stat + .2byte \slot + .endm + + @ Sets VAR_RESULT to TRUE if the Pokemon has the Gigantamax Factor, + @ or to FALSE otherwise. + .macro hasgigantamaxfactor slot:req + callnative HasGigantamaxFactor + .2byte \slot + .endm + + @ Toggles the Gigantamax Factor for a Pokemon. + @ Fails for Melmetal (vanilla behavior). + @ Sets VAR_RESULT to TRUE if it succeeds, and FALSE otherwise. + .macro togglegigantamaxfactor slot:req + callnative ToggleGigantamaxFactor + .2byte \slot + .endm diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 4cdb0ecb99ce..3943be627884 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -860,21 +860,21 @@ gBattleAnims_Moves:: .4byte Move_MATCHA_GOTCHA .4byte Move_SYRUP_BOMB .4byte Move_IVY_CUDGEL - .4byte Move_833 - .4byte Move_834 - .4byte Move_835 - .4byte Move_836 - .4byte Move_837 - .4byte Move_838 - .4byte Move_839 - .4byte Move_840 - .4byte Move_841 - .4byte Move_842 - .4byte Move_843 - .4byte Move_844 - .4byte Move_845 - .4byte Move_846 - .4byte Move_847 + .4byte Move_ELECTRO_SHOT + .4byte Move_TERA_STARSTORM + .4byte Move_FICKLE_BEAM + .4byte Move_BURNING_BULWARK + .4byte Move_THUNDERCLAP + .4byte Move_MIGHTY_CLEAVE + .4byte Move_TACHYON_CUTTER + .4byte Move_HARD_PRESS + .4byte Move_DRAGON_CHEER + .4byte Move_ALLURING_VOICE + .4byte Move_TEMPER_FLARE + .4byte Move_SUPERCELL_SLAM + .4byte Move_PSYCHIC_NOISE + .4byte Move_UPPER_HAND + .4byte Move_MALIGNANT_CHAIN @@@@ Z MOVES .4byte Move_BREAKNECK_BLITZ .4byte Move_ALL_OUT_PUMMELING @@ -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:: @@ -16977,27 +17000,25 @@ Move_HYDRO_STEAM:: Move_BLOOD_MOON:: Move_MATCHA_GOTCHA:: Move_IVY_CUDGEL:: +Move_ELECTRO_SHOT:: +Move_TERA_STARSTORM:: +Move_FICKLE_BEAM:: +Move_THUNDERCLAP:: +Move_MIGHTY_CLEAVE:: +Move_TACHYON_CUTTER:: +Move_HARD_PRESS:: +Move_DRAGON_CHEER:: +Move_TEMPER_FLARE:: +Move_SUPERCELL_SLAM:: +Move_PSYCHIC_NOISE:: +Move_UPPER_HAND:: +Move_MALIGNANT_CHAIN:: end @to do @@@@@@@@@@@@@@@@@@@@@@@ GEN 1-3 @@@@@@@@@@@@@@@@@@@@@@@ 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 @@ -19353,7 +19374,7 @@ Move_TELEPORT: call UnsetPsychicBg waitforvisualfinish end - + DoubleTeamAnimRet: setalpha 12, 8 monbg ANIM_ATK_PARTNER @@ -21848,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 @@ -23288,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 @@ -23296,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 @@ -23512,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: @@ -24859,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 @@ -24876,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 @@ -27181,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 @@ -27636,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 @@ -28816,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 @@ -28899,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 @@ -29258,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 @@ -29882,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 @@ -30075,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 @@ -30106,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 @@ -30425,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 @@ -30632,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 @@ -30852,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 @@ -31064,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 @@ -31157,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 @@ -31640,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 @@ -31963,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 @@ -32212,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 @@ -32414,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 @@ -32485,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 @@ -32639,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 @@ -32810,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 @@ -32890,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 @@ -33020,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 @@ -33167,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 @@ -33369,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 09eb96916867..cddbdcc04403 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -440,6 +440,43 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectBrickBreak @ EFFECT_RAGING_BULL .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 + attackstring + ppreduce + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_FilletAwayTryAttack + jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_FilletAwayTryAttack + jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ButItFailed +BattleScript_FilletAwayTryAttack:: + halvehp BattleScript_ButItFailed + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE + attackanimation + waitanimation + setbyte sSTAT_ANIM_PLAYED, FALSE + playstatchangeanimation BS_ATTACKER, BIT_ATK | BIT_SPATK | BIT_SPEED, STAT_CHANGE_BY_TWO + setstatchanger STAT_ATK, 2, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayTrySpAtk + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +BattleScript_FilletAwayTrySpAtk:: + setstatchanger STAT_SPATK, 2, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayTrySpeed + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +BattleScript_FilletAwayTrySpeed:: + setstatchanger STAT_SPEED, 2, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_FilletAwayEnd + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +BattleScript_FilletAwayEnd:: + bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + goto BattleScript_MoveEnd BattleScript_EffectDoodle: attackcanceler @@ -1026,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 @@ -1207,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 @@ -1661,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 @@ -5343,12 +5386,16 @@ BattleScript_EffectBellyDrum:: attackcanceler attackstring ppreduce - maxattackhalvehp BattleScript_ButItFailed + jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed + halvehp BattleScript_ButItFailed orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE attackanimation waitanimation healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER + playstatchangeanimation BS_ATTACKER, BIT_ATK, STAT_CHANGE_BY_TWO + setstatchanger STAT_ATK, MAX_STAT_STAGE, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_MoveEnd printstring STRINGID_PKMNCUTHPMAXEDATTACK waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd @@ -8064,6 +8111,7 @@ BattleScript_IllusionOff:: return BattleScript_CottonDownActivates:: + copybyte sSAVED_BATTLER, gBattlerAttacker showabilitypopup BS_TARGET pause B_WAIT_TIME_LONG destroyabilitypopup @@ -8088,6 +8136,7 @@ BattleScript_CottonDownLoopIncrement: jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_CottonDownLoop BattleScript_CottonDownReturn: swapattackerwithtarget + copybyte gBattlerAttacker, sSAVED_BATTLER return BattleScript_AnticipationActivates:: diff --git a/data/scripts/pc.inc b/data/scripts/pc.inc index 1993aaf63f86..e4e37f5b4309 100644 --- a/data/scripts/pc.inc +++ b/data/scripts/pc.inc @@ -64,3 +64,11 @@ EventScript_AccessHallOfFame:: waitstate goto EventScript_AccessPC end + +EventScript_AccessPokemonBoxLink:: + playse SE_PC_LOGIN + msgbox gText_StorageSystemOpened, MSGBOX_DEFAULT + special ShowPokemonStorageSystemPC + waitstate + goto EventScript_TurnOffPC + end 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/items/icon_palettes/metal_alloy.pal b/graphics/items/icon_palettes/metal_alloy.pal new file mode 100644 index 000000000000..83756399234e --- /dev/null +++ b/graphics/items/icon_palettes/metal_alloy.pal @@ -0,0 +1,18 @@ +JASC-PAL +0100 +15 +0 0 0 +249 253 255 +224 232 243 +169 163 177 +136 130 156 +178 194 220 +123 146 180 +162 164 202 +153 208 247 +85 96 152 +136 150 213 +186 212 247 +90 118 181 +154 195 255 +49 49 49 diff --git a/graphics/items/icons/metal_alloy.png b/graphics/items/icons/metal_alloy.png new file mode 100644 index 000000000000..408e13dd5b9b Binary files /dev/null and b/graphics/items/icons/metal_alloy.png differ 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 c41698fd5f55..fba81a802ac0 100644 --- a/include/battle.h +++ b/include/battle.h @@ -65,7 +65,7 @@ struct ResourceFlags struct DisableStruct { u32 transformedMonPersonality; - u32 transformedMonOtId; + bool8 transformedMonShininess; u16 disabledMove; u16 encoredMove; u8 protectUses:4; @@ -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; @@ -336,7 +337,7 @@ struct AI_ThinkingStruct u16 moveConsidered; s32 score[MAX_MON_MOVES]; u32 funcResult; - u32 aiFlags; + u32 aiFlags[MAX_BATTLERS_COUNT]; u8 aiAction; u8 aiLogicId; struct AI_SavedBattleMon saved[MAX_BATTLERS_COUNT]; @@ -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]; @@ -1066,7 +1068,7 @@ extern u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT]; extern u8 gBattlerInMenuId; extern bool8 gDoingBattleAnim; extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; -extern u32 gTransformedOtIds[MAX_BATTLERS_COUNT]; +extern bool8 gTransformedShininess[MAX_BATTLERS_COUNT]; extern u8 gPlayerDpadHoldFrames; extern struct BattleSpriteData *gBattleSpritesDataPtr; extern struct MonSpritesGfx *gMonSpritesGfxPtr; diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h index f8a5a01cc12f..bfb51d67bd9c 100644 --- a/include/battle_ai_util.h +++ b/include/battle_ai_util.h @@ -118,7 +118,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_anim.h b/include/battle_anim.h index 672b640cc92e..c41d94eb099e 100644 --- a/include/battle_anim.h +++ b/include/battle_anim.h @@ -159,7 +159,7 @@ void PrepareAffineAnimInTaskData(struct Task *task, u8 spriteId, const union Aff bool8 RunAffineAnimFromTaskData(struct Task *task); void AnimThrowProjectile(struct Sprite *sprite); void GetBgDataForTransform(struct BattleAnimBgData *dest, u8 battlerId); -u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId); +u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, bool8 isShiny, u32 battlerId); void ResetSpriteRotScale_PreserveAffine(struct Sprite *sprite); void Trade_MoveSelectedMonToTarget(struct Sprite *sprite); void DestroyAnimVisualTaskAndDisableBlend(u8 taskId); diff --git a/include/battle_main.h b/include/battle_main.h index b171b2f28927..2c5d88701893 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -84,8 +84,6 @@ extern const struct OamData gOamData_BattleSpriteOpponentSide; extern const struct OamData gOamData_BattleSpritePlayerSide; extern const u8 gTypeNames[NUMBER_OF_MON_TYPES][TYPE_NAME_LENGTH + 1]; extern const struct TrainerMoney gTrainerMoneyTable[]; -extern const u8 gAbilityNames[][ABILITY_NAME_LENGTH + 1]; -extern const u8 *const gAbilityDescriptionPointers[]; extern const u8 gStatusConditionString_PoisonJpn[8]; extern const u8 gStatusConditionString_SleepJpn[8]; diff --git a/include/config/battle.h b/include/config/battle.h index 7e0f05a81947..acce0ac124b1 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -109,10 +109,11 @@ #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. // Ability settings #define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters. diff --git a/include/config/item.h b/include/config/item.h index 195a78e45728..78324affeaeb 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -10,10 +10,12 @@ #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. +#define I_PRICE GEN_LATEST // Some items have varied in value across generations. +#define I_BERRY_PRICE GEN_7 // Since Berries have become unplantable (Gen8+), their price has gone up. // TM config #define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. diff --git a/include/config/overworld.h b/include/config/overworld.h index 34880644211d..513eb36723cc 100644 --- a/include/config/overworld.h +++ b/include/config/overworld.h @@ -11,6 +11,7 @@ // PC settings #define OW_PC_PRESS_B GEN_LATEST // In Gen4, pressing B when holding a Pokémon is equivalent to placing it. In Gen3, it gives the "You're holding a Pokémon!" error. #define OW_PC_JAPAN_WALDA_ICONS TRUE // In the US release of Emerald, the Cross, Bolt, and Plusle icons for Walda's wallpapers were left blank from the Japan release. Setting this to TRUE will restore them. +#define OW_PC_HEAL GEN_LATEST // In Gen8+, Pokémon are not healed when deposited in the PC. // Out-of-battle Ability effects #define OW_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8, if a Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same Nature, as opposed to 50% previously. Stationary Pokémon are excluded in Gen3. In Gen6, all No Eggs Discovered gift Pokémon will have the same Nature, while in Gen7 all gift Pokémon will, regardless of Egg Group - In Gen 8, no gift Pokémon are affected. In Gen9, this ability has no out-of-battle effect. diff --git a/include/config/pokemon.h b/include/config/pokemon.h index abdb728ac175..58c740f079ee 100644 --- a/include/config/pokemon.h +++ b/include/config/pokemon.h @@ -32,6 +32,7 @@ #define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs. #define P_EV_CAP GEN_LATEST // Since Gen 6, the max EVs per stat is 252 instead of 255. #define P_CATCH_CURVE GEN_LATEST // Since Gen 6, the capture rate curve was changed to make pokeballs more effective on lower level pokemon +#define P_SHOW_TERA_TYPE GEN_LATEST // Since Gen 9, the Tera Type is shown on the summary screen. // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. diff --git a/include/constants/abilities.h b/include/constants/abilities.h index 7e3b1728d947..3cced68bb16b 100644 --- a/include/constants/abilities.h +++ b/include/constants/abilities.h @@ -332,10 +332,10 @@ #define ABILITY_EMBODY_ASPECT_CORNERSTONE 304 #define ABILITY_TOXIC_CHAIN 305 #define ABILITY_SUPERSWEET_SYRUP 306 -#define ABILITY_307 307 -#define ABILITY_308 308 -#define ABILITY_309 309 -#define ABILITY_310 310 +#define ABILITY_TERA_SHIFT 307 +#define ABILITY_TERA_SHELL 308 +#define ABILITY_TERAFORM_ZERO 309 +#define ABILITY_POISON_PUPPETEER 310 #define ABILITIES_COUNT_GEN9 311 diff --git a/include/constants/battle.h b/include/constants/battle.h index 35addb937b3e..92688026f8cc 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -104,7 +104,10 @@ #define B_OUTCOME_LINK_BATTLE_RAN (1 << 7) // 128 // Non-volatile status conditions -// These persist remain outside of battle and after switching out +// These remain outside of battle and after switching out. +// If a new STATUS1 is added here, it should also be added to +// sCompressedStatuses in src/pokemon.c or else it will be lost outside +// of battle. #define STATUS1_NONE 0 #define STATUS1_SLEEP (1 << 0 | 1 << 1 | 1 << 2) // First 3 bits (Number of turns to sleep) #define STATUS1_SLEEP_TURN(num) ((num) << 0) // Just for readability (or if rearranging statuses) 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 420433bd02a6..b1662469e755 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -417,7 +417,10 @@ #define EFFECT_RAGING_BULL 411 #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 414 +#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/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 7f4d8ccd3a47..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 @@ -24,6 +24,8 @@ #define VERSION_PLATINUM 12 #define VERSION_GAMECUBE 15 +#define NUM_VERSIONS 15 + #define LANGUAGE_JAPANESE 1 #define LANGUAGE_ENGLISH 2 #define LANGUAGE_FRENCH 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/items.h b/include/constants/items.h index dbe8c9acd2ea..0be82dcb5f8a 100644 --- a/include/constants/items.h +++ b/include/constants/items.h @@ -986,8 +986,8 @@ #define ITEM_SWIFT_MOCHI 811 #define ITEM_FRESH_START_MOCHI 812 #define ITEM_GLIMMERING_CHARM 813 -#define ITEM_814 814 // TWV0YWwgQWxsb3k= -#define ITEM_815 815 // U3RlbGxhciBUZXJhIFNoYXJk +#define ITEM_METAL_ALLOY 814 +#define ITEM_STELLAR_TERA_SHARD 815 #define ITEMS_COUNT 816 #define ITEM_FIELD_ARROW ITEMS_COUNT diff --git a/include/constants/moves.h b/include/constants/moves.h index a8fcb01654c5..a0c0eaf3b304 100644 --- a/include/constants/moves.h +++ b/include/constants/moves.h @@ -886,25 +886,27 @@ #define MOVE_MAGICAL_TORQUE 826 #define MOVE_PSYBLADE 827 #define MOVE_HYDRO_STEAM 828 +// The Teal Mask Moves #define MOVE_BLOOD_MOON 829 #define MOVE_MATCHA_GOTCHA 830 #define MOVE_SYRUP_BOMB 831 #define MOVE_IVY_CUDGEL 832 -#define MOVE_833 833 -#define MOVE_834 834 -#define MOVE_835 835 -#define MOVE_836 836 -#define MOVE_837 837 -#define MOVE_838 838 -#define MOVE_839 839 -#define MOVE_840 840 -#define MOVE_841 841 -#define MOVE_842 842 -#define MOVE_843 843 -#define MOVE_844 844 -#define MOVE_845 845 -#define MOVE_846 846 -#define MOVE_847 847 +// The Indigo Disk Moves +#define MOVE_ELECTRO_SHOT 833 +#define MOVE_TERA_STARSTORM 834 +#define MOVE_FICKLE_BEAM 835 +#define MOVE_BURNING_BULWARK 836 +#define MOVE_THUNDERCLAP 837 +#define MOVE_MIGHTY_CLEAVE 838 +#define MOVE_TACHYON_CUTTER 839 +#define MOVE_HARD_PRESS 840 +#define MOVE_DRAGON_CHEER 841 +#define MOVE_ALLURING_VOICE 842 +#define MOVE_TEMPER_FLARE 843 +#define MOVE_SUPERCELL_SLAM 844 +#define MOVE_PSYCHIC_NOISE 845 +#define MOVE_UPPER_HAND 846 +#define MOVE_MALIGNANT_CHAIN 847 #define MOVES_COUNT_GEN9 848 @@ -1014,6 +1016,8 @@ #define MOVES_COUNT_DYNAMAX (LAST_MAX_MOVE + 1) +#define MOVES_COUNT_ALL MOVES_COUNT_DYNAMAX + // Used for checks for moves affected by Disable, Mimic, etc. #define MOVE_UNAVAILABLE 0xFFFF diff --git a/include/constants/pokedex.h b/include/constants/pokedex.h index ffbbb2eb18a8..07e8c02fe2a5 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, @@ -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 67053a281997..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 @@ -146,6 +146,8 @@ #define MIN_LEVEL 1 #define MAX_LEVEL 100 +#define MAX_DYNAMAX_LEVEL 10 + #define OT_ID_PLAYER_ID 0 #define OT_ID_PRESET 1 #define OT_ID_RANDOM_NO_SHINY 2 @@ -238,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 @@ -314,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/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 7a67fecd55a7..8a3b6a3c6558 100644 --- a/include/contest.h +++ b/include/contest.h @@ -107,7 +107,9 @@ struct ContestPokemon u8 sheen; u8 highestRank; bool8 gameCleared; - u8 unused[10]; + u8 isShiny:1; + u8 unused1:7; + u8 unused2[9]; u32 personality; u32 otId; }; @@ -125,6 +127,8 @@ struct ContestMoveAnimData u16 species; u16 targetSpecies; bool8 hasTargetAnim:1; + u8 isShiny:1; + u8 targetIsShiny:1; u8 contestant; u32 personality; u32 otId; @@ -210,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/data.h b/include/data.h index a5918fcb98cf..6351b6eb16f6 100644 --- a/include/data.h +++ b/include/data.h @@ -66,6 +66,8 @@ struct TrainerMon u8 nature : 5; bool8 gender : 2; bool8 isShiny : 1; + u8 dynamaxLevel : 4; + bool8 gigantamaxFactor : 1; }; #define TRAINER_PARTY(partyArray) partyArray, .partySize = ARRAY_COUNT(partyArray) diff --git a/include/event_scripts.h b/include/event_scripts.h index 153935695900..8df303ca335c 100644 --- a/include/event_scripts.h +++ b/include/event_scripts.h @@ -515,6 +515,7 @@ extern const u8 MauvilleCity_PokemonCenter_1F_Text_HotSpringsStory[]; extern const u8 LittlerootTown_BrendansHouse_2F_EventScript_PC[]; extern const u8 LittlerootTown_MaysHouse_2F_EventScript_PC[]; extern const u8 EventScript_PC[]; +extern const u8 EventScript_AccessPokemonBoxLink[]; extern const u8 EventScript_TestSignpostMsg[]; extern const u8 EventScript_HiddenItemScript[]; extern const u8 EventScript_TV[]; diff --git a/include/global.h b/include/global.h index 60abf094af3e..4ec9407912cf 100644 --- a/include/global.h +++ b/include/global.h @@ -129,8 +129,8 @@ #define CAT(a, b) CAT_(a, b) #define CAT_(a, b) a ## b -#define STR(a) STR_(a) -#define STR_(a) #a +#define STR(...) STR_(__VA_ARGS__) +#define STR_(...) #__VA_ARGS__ // Converts a string to a compound literal, essentially making it a pointer to const u8 #define COMPOUND_STRING(str) (const u8[]) _(str) @@ -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]; @@ -738,7 +738,8 @@ struct ContestWinner u8 contestCategory; u8 monName[POKEMON_NAME_LENGTH + 1]; u8 trainerName[PLAYER_NAME_LENGTH + 1]; - u8 contestRank; + u8 contestRank:7; + bool8 isShiny:1; //u8 padding; }; diff --git a/include/graphics.h b/include/graphics.h index 9d7258e32db9..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[]; @@ -785,6 +785,8 @@ extern const u32 gItemIcon_UnremarkableTeacup[]; extern const u32 gItemIconPalette_UnremarkableTeacup[]; extern const u32 gItemIcon_MasterpieceTeacup[]; extern const u32 gItemIconPalette_MasterpieceTeacup[]; +extern const u32 gItemIcon_MetalAlloy[]; +extern const u32 gItemIconPalette_MetalAlloy[]; // Nectars extern const u32 gItemIcon_RedNectar[]; extern const u32 gItemIconPalette_RedNectar[]; @@ -1909,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[]; @@ -3131,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[]; @@ -3263,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/item.h b/include/item.h index da6faa4864db..33f8ea9ee044 100644 --- a/include/item.h +++ b/include/item.h @@ -62,7 +62,7 @@ u16 CountTotalItemQuantityInBag(u16 itemId); bool8 AddPyramidBagItem(u16 itemId, u16 count); bool8 RemovePyramidBagItem(u16 itemId, u16 count); const u8 *ItemId_GetName(u16 itemId); -u16 ItemId_GetPrice(u16 itemId); +u32 ItemId_GetPrice(u16 itemId); u32 ItemId_GetHoldEffect(u32 itemId); u32 ItemId_GetHoldEffectParam(u32 itemId); const u8 *ItemId_GetDescription(u16 itemId); diff --git a/include/item_use.h b/include/item_use.h index 3117e603d519..a5fe1ee97f73 100644 --- a/include/item_use.h +++ b/include/item_use.h @@ -7,18 +7,21 @@ void ItemUseOutOfBattle_Rod(u8); void ItemUseOutOfBattle_Itemfinder(u8); void ItemUseOutOfBattle_PokeblockCase(u8); void ItemUseOutOfBattle_CoinCase(u8); +void ItemUseOutOfBattle_PokemonBoxLink(u8); void ItemUseOutOfBattle_PowderJar(u8); void ItemUseOutOfBattle_SSTicket(u8); void ItemUseOutOfBattle_WailmerPail(u8); void ItemUseOutOfBattle_Medicine(u8); void ItemUseOutOfBattle_AbilityCapsule(u8); void ItemUseOutOfBattle_AbilityPatch(u8); +void ItemUseOutOfBattle_Mint(u8); void ItemUseOutOfBattle_ResetEVs(u8); void ItemUseOutOfBattle_ReduceEV(u8); void ItemUseOutOfBattle_SacredAsh(u8); void ItemUseOutOfBattle_PPRecovery(u8); void ItemUseOutOfBattle_PPUp(u8); void ItemUseOutOfBattle_RareCandy(u8); +void ItemUseOutOfBattle_DynamaxCandy(u8); void ItemUseOutOfBattle_TMHM(u8); void ItemUseOutOfBattle_Repel(u8); void ItemUseOutOfBattle_Lure(u8); diff --git a/include/party_menu.h b/include/party_menu.h index c50abc276a69..1352f54a4386 100644 --- a/include/party_menu.h +++ b/include/party_menu.h @@ -53,6 +53,7 @@ void ItemUseCB_BattleChooseMove(u8 taskId, TaskFunc task); void ItemUseCB_Medicine(u8 taskId, TaskFunc task); void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task); void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task); +void ItemUseCB_Mint(u8 taskId, TaskFunc task); void ItemUseCB_ResetEVs(u8 taskId, TaskFunc task); void ItemUseCB_ReduceEV(u8 taskId, TaskFunc task); void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task); @@ -62,6 +63,7 @@ bool8 MonKnowsMove(struct Pokemon *mon, u16 move); bool8 BoxMonKnowsMove(struct BoxPokemon *boxMon, u16 move); void ItemUseCB_TMHM(u8 taskId, TaskFunc task); void ItemUseCB_RareCandy(u8 taskId, TaskFunc task); +void ItemUseCB_DynamaxCandy(u8 taskId, TaskFunc task); void ItemUseCB_SacredAsh(u8 taskId, TaskFunc task); void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task); void ItemUseCB_FormChange(u8 taskId, TaskFunc task); diff --git a/include/pokedex.h b/include/pokedex.h index 39b45fc5ff8a..c2169c699435 100644 --- a/include/pokedex.h +++ b/include/pokedex.h @@ -21,7 +21,7 @@ enum void ResetPokedex(void); u16 GetNationalPokedexCount(u8); u16 GetHoennPokedexCount(u8); -u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality); +u8 DisplayCaughtMonDexPage(u16 species, bool32 isShiny, u32 personality); s8 GetSetPokedexFlag(u16 nationalNum, u8 caseId); u16 CreateMonSpriteFromNationalDexNumber(u16, s16, s16, u16); bool16 HasAllHoennMons(void); diff --git a/include/pokemon.h b/include/pokemon.h index b081a86fef72..6ce793a19e13 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -12,8 +12,8 @@ // Property labels for Get(Box)MonData / Set(Box)MonData enum { MON_DATA_PERSONALITY, + MON_DATA_STATUS, MON_DATA_OT_ID, - MON_DATA_NICKNAME, MON_DATA_LANGUAGE, MON_DATA_SANITY_IS_BAD_EGG, MON_DATA_SANITY_HAS_SPECIES, @@ -21,7 +21,12 @@ enum { MON_DATA_OT_NAME, MON_DATA_MARKINGS, MON_DATA_CHECKSUM, + MON_DATA_HP, + MON_DATA_IS_SHINY, + MON_DATA_HIDDEN_NATURE, + MON_DATA_HP_LOST, MON_DATA_ENCRYPT_SEPARATOR, + MON_DATA_NICKNAME, MON_DATA_SPECIES, MON_DATA_HELD_ITEM, MON_DATA_MOVE1, @@ -66,9 +71,7 @@ enum { MON_DATA_CUTE_RIBBON, MON_DATA_SMART_RIBBON, MON_DATA_TOUGH_RIBBON, - MON_DATA_STATUS, MON_DATA_LEVEL, - MON_DATA_HP, MON_DATA_MAX_HP, MON_DATA_ATK, MON_DATA_DEF, @@ -90,7 +93,6 @@ enum { MON_DATA_NATIONAL_RIBBON, MON_DATA_EARTH_RIBBON, MON_DATA_WORLD_RIBBON, - MON_DATA_UNUSED_RIBBONS, MON_DATA_MODERN_FATEFUL_ENCOUNTER, MON_DATA_KNOWN_MOVES, MON_DATA_RIBBON_COUNT, @@ -100,87 +102,116 @@ enum { MON_DATA_SPEED2, MON_DATA_SPATK2, MON_DATA_SPDEF2, + MON_DATA_HYPER_TRAINED_HP, + MON_DATA_HYPER_TRAINED_ATK, + MON_DATA_HYPER_TRAINED_DEF, + MON_DATA_HYPER_TRAINED_SPEED, + MON_DATA_HYPER_TRAINED_SPATK, + MON_DATA_HYPER_TRAINED_SPDEF, + MON_DATA_IS_SHADOW, + MON_DATA_DYNAMAX_LEVEL, + MON_DATA_GIGANTAMAX_FACTOR, + MON_DATA_TERA_TYPE, }; struct PokemonSubstruct0 { - /*0x00*/ u16 species; - /*0x02*/ u16 heldItem; - /*0x04*/ u32 experience; - /*0x08*/ u8 ppBonuses; - /*0x09*/ u8 friendship; - /*0x0A*/ u16 pokeball:5; //31 balls - u16 filler:11; -}; /* size = 12 */ + u16 species:11; // 2047 species. + u16 teraType:5; // 30 types. + u16 heldItem:10; // 1023 items. + u16 unused_02:6; + u32 experience:21; + u32 nickname11:8; // 11th character of nickname. + u32 unused_04:3; + u8 ppBonuses; + u8 friendship; + u16 pokeball:6; // 63 balls. + u16 nickname12:8; // 12th character of nickname. + u16 unused_0A:2; +}; struct PokemonSubstruct1 { - /*0x00*/ u16 moves[MAX_MON_MOVES]; - /*0x08*/ u8 pp[MAX_MON_MOVES]; -}; /* size = 12 */ + u16 move1:11; // 2047 moves. + u16 unused_00:5; + u16 move2:11; // 2047 moves. + u16 unused_02:5; + u16 move3:11; // 2047 moves. + u16 unused_04:5; + u16 move4:11; // 2047 moves. + u16 unused_06:3; + u16 hyperTrainedHP:1; + u16 hyperTrainedAttack:1; + u8 pp1:7; // 127 PP. + u8 hyperTrainedDefense:1; + u8 pp2:7; // 127 PP. + u8 hyperTrainedSpeed:1; + u8 pp3:7; // 127 PP. + u8 hyperTrainedSpAttack:1; + u8 pp4:7; // 127 PP. + u8 hyperTrainedSpDefense:1; +}; struct PokemonSubstruct2 { - /*0x00*/ u8 hpEV; - /*0x01*/ u8 attackEV; - /*0x02*/ u8 defenseEV; - /*0x03*/ u8 speedEV; - /*0x04*/ u8 spAttackEV; - /*0x05*/ u8 spDefenseEV; - /*0x06*/ u8 cool; - /*0x07*/ u8 beauty; - /*0x08*/ u8 cute; - /*0x09*/ u8 smart; - /*0x0A*/ u8 tough; - /*0x0B*/ u8 sheen; -}; /* size = 12 */ + u8 hpEV; + u8 attackEV; + u8 defenseEV; + u8 speedEV; + u8 spAttackEV; + u8 spDefenseEV; + u8 cool; + u8 beauty; + u8 cute; + u8 smart; + u8 tough; + u8 sheen; +}; struct PokemonSubstruct3 { - /* 0x00 */ u8 pokerus; - /* 0x01 */ u8 metLocation; - - /* 0x02 */ u16 metLevel:7; - /* 0x02 */ u16 metGame:4; - /* 0x03 */ u16 unused1:4; - /* 0x03 */ u16 otGender:1; - - /* 0x04 */ u32 hpIV:5; - /* 0x04 */ u32 attackIV:5; - /* 0x05 */ u32 defenseIV:5; - /* 0x05 */ u32 speedIV:5; - /* 0x05 */ u32 spAttackIV:5; - /* 0x06 */ u32 spDefenseIV:5; - /* 0x07 */ u32 isEgg:1; - /* 0x07 */ u32 unused2:1; - - /* 0x08 */ u32 coolRibbon:3; // Stores the highest contest rank achieved in the Cool category. - /* 0x08 */ u32 beautyRibbon:3; // Stores the highest contest rank achieved in the Beauty category. - /* 0x08 */ u32 cuteRibbon:3; // Stores the highest contest rank achieved in the Cute category. - /* 0x09 */ u32 smartRibbon:3; // Stores the highest contest rank achieved in the Smart category. - /* 0x09 */ u32 toughRibbon:3; // Stores the highest contest rank achieved in the Tough category. - /* 0x09 */ u32 championRibbon:1; // Given when defeating the Champion. Because both RSE and FRLG use it, later generations don't specify from which region it comes from. - /* 0x0A */ u32 winningRibbon:1; // Given at the Battle Tower's Level 50 challenge by winning a set of seven battles that extends the current streak to 56 or more. - /* 0x0A */ u32 victoryRibbon:1; // Given at the Battle Tower's Level 100 challenge by winning a set of seven battles that extends the current streak to 56 or more. - /* 0x0A */ u32 artistRibbon:1; // Given at the Contest Hall by winning a Master Rank contest with at least 800 points, and agreeing to have the Pokémon's portrait placed in the museum after being offered. - /* 0x0A */ u32 effortRibbon:1; // Given at Slateport's market to Pokémon with maximum EVs. - /* 0x0A */ u32 marineRibbon:1; // Never distributed. - /* 0x0A */ u32 landRibbon:1; // Never distributed. - /* 0x0A */ u32 skyRibbon:1; // Never distributed. - /* 0x0A */ u32 countryRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. - /* 0x0B */ u32 nationalRibbon:1; // Given to purified Shadow Pokémon in Colosseum/XD. - /* 0x0B */ u32 earthRibbon:1; // Given to teams that have beaten Mt. Battle's 100-battle challenge in Colosseum/XD. - /* 0x0B */ u32 worldRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. - /* 0x0B */ u32 unusedRibbons:2; // Discarded in Gen 4. - /* 0x0B */ u32 abilityNum:2; - - // The functionality of this bit changed in FRLG: - // In RS, this bit does nothing, is never set, & is accidentally unset when hatching Eggs. - // In FRLG & Emerald, this controls Mew & Deoxys obedience and whether they can be traded. - // If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens. - // Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness. - // Not to be confused with METLOC_FATEFUL_ENCOUNTER. - /* 0x0B */ u32 modernFatefulEncounter:1; + u8 pokerus; + u8 metLocation; + u16 metLevel:7; + u16 metGame:4; + u16 dynamaxLevel:4; + u16 otGender:1; + u32 hpIV:5; + u32 attackIV:5; + u32 defenseIV:5; + u32 speedIV:5; + u32 spAttackIV:5; + u32 spDefenseIV:5; + u32 isEgg:1; + u32 gigantamaxFactor:1; + u32 coolRibbon:3; // Stores the highest contest rank achieved in the Cool category. + u32 beautyRibbon:3; // Stores the highest contest rank achieved in the Beauty category. + u32 cuteRibbon:3; // Stores the highest contest rank achieved in the Cute category. + u32 smartRibbon:3; // Stores the highest contest rank achieved in the Smart category. + u32 toughRibbon:3; // Stores the highest contest rank achieved in the Tough category. + u32 championRibbon:1; // Given when defeating the Champion. Because both RSE and FRLG use it, later generations don't specify from which region it comes from. + u32 winningRibbon:1; // Given at the Battle Tower's Level 50 challenge by winning a set of seven battles that extends the current streak to 56 or more. + u32 victoryRibbon:1; // Given at the Battle Tower's Level 100 challenge by winning a set of seven battles that extends the current streak to 56 or more. + u32 artistRibbon:1; // Given at the Contest Hall by winning a Master Rank contest with at least 800 points, and agreeing to have the Pokémon's portrait placed in the museum after being offered. + u32 effortRibbon:1; // Given at Slateport's market to Pokémon with maximum EVs. + u32 marineRibbon:1; // Never distributed. + u32 landRibbon:1; // Never distributed. + u32 skyRibbon:1; // Never distributed. + u32 countryRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. + u32 nationalRibbon:1; // Given to purified Shadow Pokémon in Colosseum/XD. + u32 earthRibbon:1; // Given to teams that have beaten Mt. Battle's 100-battle challenge in Colosseum/XD. + u32 worldRibbon:1; // Distributed during Pokémon Festa '04 and '05 to tournament winners. + u32 isShadow:1; + u32 unused_0B:1; + u32 abilityNum:2; + + // The functionality of this bit changed in FRLG: + // In RS, this bit does nothing, is never set, & is accidentally unset when hatching Eggs. + // In FRLG & Emerald, this controls Mew & Deoxys obedience and whether they can be traded. + // If set, a Pokémon is a fateful encounter in FRLG's summary screen if hatched & for all Pokémon in Gen 4+ summary screens. + // Set for in-game event island legendaries, events distributed after a certain date, & Pokémon from XD: Gale of Darkness. + // Not to be confused with METLOC_FATEFUL_ENCOUNTER. + u32 modernFatefulEncounter:1; }; // Number of bytes in the largest Pokémon substruct. @@ -205,17 +236,21 @@ struct BoxPokemon { u32 personality; u32 otId; - u8 nickname[POKEMON_NAME_LENGTH]; - u8 language; + u8 nickname[min(10, POKEMON_NAME_LENGTH)]; + u8 language:3; + u8 hiddenNatureModifier:5; // 31 natures. u8 isBadEgg:1; u8 hasSpecies:1; u8 isEgg:1; - u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set - u8 unused:4; + u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set. + u8 unused_13:4; u8 otName[PLAYER_NAME_LENGTH]; - u8 markings; + u8 markings:4; + u8 compressedStatus:4; u16 checksum; - u16 unknown; + u16 hpLost:14; // 16383 HP. + u16 shinyModifier:1; + u16 unused_1E:1; union { @@ -301,6 +336,7 @@ struct BattlePokemon /*0x51*/ u32 status2; /*0x55*/ u32 otId; /*0x59*/ u8 metLevel; + /*0x5A*/ bool8 isShiny; }; struct Evolution @@ -468,10 +504,17 @@ struct BattleMove u32 encoreBanned:1; u32 parentalBondBanned:1; u32 skyBattleBanned:1; + u32 sketchBanned:1; u16 argument; }; +struct Ability +{ + u8 name[ABILITY_NAME_LENGTH + 1]; + const u8 *description; +}; + #define SPINDA_SPOT_WIDTH 16 #define SPINDA_SPOT_HEIGHT 16 @@ -540,6 +583,7 @@ extern const u16 gUnionRoomFacilityClasses[]; extern const struct SpriteTemplate gBattlerSpriteTemplates[]; extern const s8 gNatureStatTable[][5]; extern const u32 sExpCandyExperienceTable[]; +extern const struct Ability gAbilities[]; void ZeroBoxMonData(struct BoxPokemon *boxMon); void ZeroMonData(struct Pokemon *mon); @@ -673,7 +717,7 @@ void PlayBattleBGM(void); void PlayMapChosenOrBattleBGM(u16 songId); void CreateTask_PlayMapChosenOrBattleBGM(u16 songId); const u32 *GetMonFrontSpritePal(struct Pokemon *mon); -const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality); +const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality); bool8 IsMoveHM(u16 move); bool8 IsMonSpriteNotFlipped(u16 species); s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor); @@ -685,7 +729,6 @@ void BoxMonRestorePP(struct BoxPokemon *boxMon); void SetMonPreventsSwitchingString(void); void SetWildMonHeldItem(void); bool8 IsMonShiny(struct Pokemon *mon); -bool8 IsShinyOtIdPersonality(u32 otId, u32 personality); const u8 *GetTrainerPartnerName(void); void BattleAnimateFrontSprite(struct Sprite *sprite, u16 species, bool8 noCry, u8 panMode); void DoMonFrontSpriteAnimation(struct Sprite *sprite, u16 species, bool8 noCry, u8 panModeAnimFlag); @@ -719,5 +762,7 @@ u16 SanitizeSpeciesId(u16 species); bool32 IsSpeciesEnabled(u16 species); u16 GetCryIdBySpecies(u16 species); u16 GetSpeciesPreEvolution(u16 species); +void HealPokemon(struct Pokemon *mon); +void HealBoxPokemon(struct BoxPokemon *boxMon); #endif // GUARD_POKEMON_H 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 9184b4663a1d..589c2b46462c 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/battle.h b/include/test/battle.h index ee410321024e..581546f87b63 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -849,6 +849,10 @@ struct moveWithPP { #define Friendship(friendship) Friendship_(__LINE__, friendship) #define Status1(status1) Status1_(__LINE__, status1) #define OTName(otName) do {static const u8 otName_[] = _(otName); OTName_(__LINE__, otName_);} while (0) +#define DynamaxLevel(dynamaxLevel) DynamaxLevel_(__LINE__, dynamaxLevel) +#define GigantamaxFactor(gigantamaxFactor) GigantamaxFactor_(__LINE__, gigantamaxFactor) +#define TeraType(teraType) TeraType_(__LINE__, teraType) +#define Shadow(isShadow) Shadow_(__LINE__, shadow) void SetFlagForTest(u32 sourceLine, u16 flagId); void ClearFlagAfterTest(void); @@ -875,6 +879,10 @@ void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]); void Friendship_(u32 sourceLine, u32 friendship); void Status1_(u32 sourceLine, u32 status1); void OTName_(u32 sourceLine, const u8 *otName); +void DynamaxLevel_(u32 sourceLine, u32 dynamaxLevel); +void GigantamaxFactor_(u32 sourceLine, bool32 gigantamaxFactor); +void TeraType_(u32 sourceLine, u32 teraType); +void Shadow_(u32 sourceLine, bool32 isShadow); // Created for easy use of EXPECT_MOVES, so the user can provide 1, 2, 3 or 4 moves for AI which can pass the test. struct FourMoves diff --git a/include/test/overworld_script.h b/include/test/overworld_script.h new file mode 100644 index 000000000000..e2f65930f5d1 --- /dev/null +++ b/include/test/overworld_script.h @@ -0,0 +1,48 @@ +/* Embedded DSL for testing overworld scripts in isolation. + * The overworld is not available, so it is only possible to test + * commands which don't affect the overworld itself, e.g. givemon can + * be tested because it only alters gPlayerParty, but addobject cannot + * because it affects object events (which aren't loaded). + * + * OVERWORLD_SCRIPT(instructions...) + * Returns a pointer to a compiled overworld script. Cannot be used to + * initialize global const data, although the pointer IS to const data. + * Note that each script command must be followed by a ;, e.g.: + * const u8 *myScript = OVERWORLD_SCRIPT( + * random 2; + * addvar VAR_RESULT, 1; + * ); + * + * RUN_OVERWORLD_SCRIPT(instructions...) + * Runs an overworld script in the immediate script context, which means + * that commands like waitstate are not supported. + * RUN_OVERWORLD_SCRIPT( + * setvar VAR_RESULT, 3; + * ); + * EXPECT_EQ(GetVar(VAR_RESULT), 3); */ +#ifndef GUARD_TEST_OVERWORLD_SCRIPT +#define GUARD_TEST_OVERWORLD_SCRIPT + +#include "script.h" +#include "test/test.h" + +#define OVERWORLD_SCRIPT(...) \ + ({ \ + const u8 *_script; \ + asm("mov %0, pc\n" \ + "b .Lend" STR(__LINE__) "\n" \ + STR(__VA_ARGS__) \ + "\n" \ + "end\n" \ + ".balign 2\n" \ + ".Lend" STR(__LINE__) ":\n" \ + : "=r" (_script)); \ + _script; \ + }) + +#define RUN_OVERWORLD_SCRIPT(...) RunScriptImmediately(OVERWORLD_SCRIPT(__VA_ARGS__)) + +// Make overworld script macros available. +asm(".include \"asm/macros/event.inc\"\n"); + +#endif diff --git a/include/test/test.h b/include/test/test.h index e9c920bd0b48..790563e77227 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -59,8 +59,9 @@ extern const struct TestRunner gAssumptionsRunner; struct FunctionTestRunnerState { - u8 parameters; - u8 runParameter; + u16 parameters; + u16 runParameter; + u16 checkProgressParameter; }; extern const struct TestRunner gFunctionTestRunner; @@ -165,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/include/trainer_pokemon_sprites.h b/include/trainer_pokemon_sprites.h index e56ed0ffa57b..7c83ca62eeb1 100644 --- a/include/trainer_pokemon_sprites.h +++ b/include/trainer_pokemon_sprites.h @@ -8,8 +8,8 @@ #define F_MON_PIC_NO_AFFINE (1 << 7) bool16 ResetAllPicSprites(void); -u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag); -u16 CreateMonPicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag); +u16 CreateMonPicSprite_Affine(u16 species, bool8 isShiny, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag); +u16 CreateMonPicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag); u16 FreeAndDestroyMonPicSprite(u16 spriteId); u16 CreateTrainerPicSprite(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag); u16 FreeAndDestroyTrainerPicSprite(u16 spriteId); diff --git a/ld_script_test.ld b/ld_script_test.ld index b86302f8cb9a..49a0ec35b0b7 100644 --- a/ld_script_test.ld +++ b/ld_script_test.ld @@ -109,6 +109,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/apprentice.c b/src/apprentice.c index dc7ac92a86d0..8c9128b71864 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -207,14 +207,7 @@ static void ShuffleApprenticeSpecies(void) for (i = 0; i < ARRAY_COUNT(species); i++) species[i] = i; - // Shuffle the possible species an arbitrary 50 times - for (i = 0; i < 50; i++) - { - u8 temp; - u8 rand1 = Random() % ARRAY_COUNT(species); - u8 rand2 = Random() % ARRAY_COUNT(species); - SWAP(species[rand1], species[rand2], temp); - } + Shuffle(species, APPRENTICE_SPECIES_COUNT, sizeof(species[0])); for (i = 0; i < MULTI_PARTY_SIZE; i++) PLAYER_APPRENTICE.speciesIds[i] = ((species[i * 2] & 0xF) << 4) | ((species[i * 2 + 1]) & 0xF); @@ -254,33 +247,19 @@ static void SetRandomQuestionData(void) u8 questionOrder[APPRENTICE_MAX_QUESTIONS + 1]; u8 partyOrder[MULTI_PARTY_SIZE]; u8 partySlot; + u8 rand; u8 i, j; - u8 rand1, rand2; u8 id; for (i = 0; i < ARRAY_COUNT(partyOrder); i++) partyOrder[i] = i; - // Shuffle the party an arbitrary 10 times - for (i = 0; i < 10; i++) - { - u8 temp; - rand1 = Random() % ARRAY_COUNT(partyOrder); - rand2 = Random() % ARRAY_COUNT(partyOrder); - SWAP(partyOrder[rand1], partyOrder[rand2], temp); - } + Shuffle(partyOrder, MULTI_PARTY_SIZE, sizeof(partyOrder[0])); for (i = 0; i < ARRAY_COUNT(questionOrder); i++) questionOrder[i] = sQuestionPossibilities[i]; - // Shuffle the questions an arbitrary 50 times - for (i = 0; i < 50; i++) - { - u8 temp; - rand1 = Random() % ARRAY_COUNT(questionOrder); - rand2 = Random() % ARRAY_COUNT(questionOrder); - SWAP(questionOrder[rand1], questionOrder[rand2], temp); - } + Shuffle(questionOrder, APPRENTICE_MAX_QUESTIONS + 1, sizeof(questionOrder[0])); gApprenticePartyMovesData = AllocZeroed(sizeof(*gApprenticePartyMovesData)); gApprenticePartyMovesData->moveCounter = 0; @@ -302,16 +281,16 @@ static void SetRandomQuestionData(void) { do { - rand1 = Random() % MAX_MON_MOVES; + rand = Random() % MAX_MON_MOVES; for (j = 0; j < gApprenticePartyMovesData->moveCounter + 1; j++) { - if (gApprenticePartyMovesData->moveSlots[id][j] == rand1) + if (gApprenticePartyMovesData->moveSlots[id][j] == rand) break; } } while (j != gApprenticePartyMovesData->moveCounter + 1); - gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand1; - PLAYER_APPRENTICE.questions[i].moveSlot = rand1; + gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand; + PLAYER_APPRENTICE.questions[i].moveSlot = rand; PLAYER_APPRENTICE.questions[i].data = GetRandomAlternateMove(PLAYER_APPRENTICE.questions[i].monId); } } diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 8980691356a9..b71270a13850 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -22,6 +22,7 @@ #include "constants/hold_effects.h" #include "constants/moves.h" #include "constants/items.h" +#include "constants/trainers.h" #define AI_ACTION_DONE (1 << 0) #define AI_ACTION_FLEE (1 << 1) @@ -139,36 +140,76 @@ static u32 GetWildAiFlags(void) return flags; } +static u32 GetAiFlags(u16 trainerId) +{ + u32 flags = 0; + + if (!(gBattleTypeFlags & BATTLE_TYPE_HAS_AI) && !IsWildMonSmart()) + return 0; + if (trainerId == 0xFFFF) + { + flags = GetWildAiFlags(); + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + flags = GetAiScriptsInRecordedBattle(); + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + flags = AI_FLAG_SAFARI; + else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) + flags = AI_FLAG_ROAMING; + else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + flags = AI_FLAG_FIRST_BATTLE; + else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) + flags = GetAiScriptsInBattleFactory(); + else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE)) + flags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT; + else + flags = gTrainers[trainerId].aiFlags; + } + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + flags |= AI_FLAG_DOUBLE_BATTLE; + + return flags; +} + void BattleAI_SetupFlags(void) { + AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_LEFT] = 0; // player has no AI + #if DEBUG_OVERWORLD_MENU == TRUE if (gIsDebugBattle) - AI_THINKING_STRUCT->aiFlags = gDebugAIFlags; - else + { + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] = gDebugAIFlags; + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = gDebugAIFlags; + return; + } #endif - if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle(); - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - AI_THINKING_STRUCT->aiFlags = AI_FLAG_SAFARI; - else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) - AI_THINKING_STRUCT->aiFlags = AI_FLAG_ROAMING; - else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) - AI_THINKING_STRUCT->aiFlags = AI_FLAG_FIRST_BATTLE; - else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory(); - else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE)) - AI_THINKING_STRUCT->aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT; - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; - else - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; - // check smart wild AI - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)) && IsWildMonSmart()) - AI_THINKING_STRUCT->aiFlags |= GetWildAiFlags(); + if (IsWildMonSmart() && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))) + { + // smart wild AI + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] = GetAiFlags(0xFFFF); + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = GetAiFlags(0xFFFF); + } + else + { + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] = GetAiFlags(gTrainerBattleOpponent_A); + if (gTrainerBattleOpponent_B != 0) + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = GetAiFlags(gTrainerBattleOpponent_B); + else + AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] = AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT]; + } - if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS) || gTrainers[gTrainerBattleOpponent_A].doubleBattle) - AI_THINKING_STRUCT->aiFlags |= AI_FLAG_DOUBLE_BATTLE; // Act smart in doubles and don't attack your partner. + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = GetAiFlags(gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)); + } + else + { + AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = 0; // player + } } // sBattler_AI set in ComputeBattleAiScores @@ -176,11 +217,12 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler) { s32 i; u8 moveLimitations; + u32 flags[MAX_BATTLERS_COUNT]; // Clear AI data but preserve the flags. - u32 flags = AI_THINKING_STRUCT->aiFlags; + memcpy(&flags[0], &AI_THINKING_STRUCT->aiFlags[0], sizeof(u32) * MAX_BATTLERS_COUNT); memset(AI_THINKING_STRUCT, 0, sizeof(struct AI_ThinkingStruct)); - AI_THINKING_STRUCT->aiFlags = flags; + memcpy(&AI_THINKING_STRUCT->aiFlags[0], &flags[0], sizeof(u32) * MAX_BATTLERS_COUNT); // Conditional score reset, unlike Ruby. for (i = 0; i < MAX_MON_MOVES; i++) @@ -251,7 +293,7 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side) void Ai_InitPartyStruct(void) { u32 i; - bool32 isOmniscient = (AI_THINKING_STRUCT->aiFlags & AI_FLAG_OMNISCIENT); + bool32 isOmniscient = (AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] & AI_FLAG_OMNISCIENT) || (AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] & AI_FLAG_OMNISCIENT); struct Pokemon *mon; AI_PARTY->count[B_SIDE_PLAYER] = gPlayerPartyCount; @@ -433,13 +475,13 @@ static bool32 AI_ShouldSwitchIfBadMoves(u32 battler, bool32 doubleBattle) if (CountUsablePartyMons(battler) > 0 && !IsBattlerTrapped(battler, TRUE) && !(gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_PALACE)) - && AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_PREFER_BATON_PASS)) + && AI_THINKING_STRUCT->aiFlags[battler] & (AI_FLAG_CHECK_VIABILITY | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_PREFER_BATON_PASS)) { // Consider switching if all moves are worthless to use. if (GetTotalBaseStat(gBattleMons[battler].species) >= 310 // Mon is not weak. && gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 2) // Mon has more than 50% of its HP { - s32 cap = AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY) ? 95 : 93; + s32 cap = AI_THINKING_STRUCT->aiFlags[battler] & (AI_FLAG_CHECK_VIABILITY) ? 95 : 93; if (doubleBattle) { for (i = 0; i < MAX_BATTLERS_COUNT; i++) @@ -492,7 +534,7 @@ static u32 ChooseMoveOrAction_Singles(u32 battlerAi) u8 consideredMoveArray[MAX_MON_MOVES]; u32 numOfBestMoves; s32 i; - u32 flags = AI_THINKING_STRUCT->aiFlags; + u32 flags = AI_THINKING_STRUCT->aiFlags[battlerAi]; AI_DATA->partnerMove = 0; // no ally while (flags != 0) @@ -577,7 +619,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi) AI_DATA->partnerMove = GetAllyChosenMove(battlerAi); AI_THINKING_STRUCT->aiLogicId = 0; AI_THINKING_STRUCT->movesetIndex = 0; - flags = AI_THINKING_STRUCT->aiFlags; + flags = AI_THINKING_STRUCT->aiFlags[sBattler_AI]; while (flags != 0) { @@ -1017,7 +1059,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_EXPLOSION: - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE)) + if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_WILL_SUICIDE)) ADJUST_SCORE(-2); if (effectiveness == AI_EFFECTIVENESS_x0) @@ -1657,6 +1699,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-6); break; case EFFECT_BELLY_DRUM: + case EFFECT_FILLET_AWAY: if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY) ADJUST_SCORE(-10); else if (aiData->hpPercents[battlerAtk] <= 60) @@ -1996,7 +2039,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } } - /*if (AI_THINKING_STRUCT->aiFlags == AI_SCRIPT_CHECK_BAD_MOVE //Only basic AI + /*if (AI_THINKING_STRUCT->aiFlags[battlerAtk] == AI_SCRIPT_CHECK_BAD_MOVE //Only basic AI && IS_DOUBLE_BATTLE) //Make the regular AI know how to use Protect minimally in Doubles { u8 shouldProtect = ShouldProtect(battlerAtk, battlerDef, move); @@ -2803,7 +2846,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) switch (atkPartnerAbility) { case ABILITY_VOLT_ABSORB: - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_HP_AWARE)) + if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_HP_AWARE)) { RETURN_SCORE_MINUS(10); } @@ -2824,7 +2867,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case ABILITY_WATER_ABSORB: case ABILITY_DRY_SKIN: - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_HP_AWARE)) + if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_HP_AWARE)) { RETURN_SCORE_MINUS(10); } @@ -3233,7 +3276,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score } // check status move preference - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0) ADJUST_SCORE(1); // check thawing moves @@ -3241,7 +3284,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(10); // check burn / frostbite - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING && AI_DATA->abilities[battlerAtk] == ABILITY_NATURAL_CURE) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING && AI_DATA->abilities[battlerAtk] == ABILITY_NATURAL_CURE) { if ((gBattleMons[battlerAtk].status1 & STATUS1_BURN && HasOnlyMovesWithCategory(battlerAtk, BATTLE_CATEGORY_PHYSICAL, TRUE)) || (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && HasOnlyMovesWithCategory(battlerAtk, BATTLE_CATEGORY_SPECIAL, TRUE))) @@ -3263,7 +3306,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(2); case EFFECT_EXPLOSION: case EFFECT_MEMENTO: - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE && gBattleMons[battlerDef].statStages[STAT_EVASION] < 7) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_WILL_SUICIDE && gBattleMons[battlerDef].statStages[STAT_EVASION] < 7) { if (aiData->hpPercents[battlerAtk] < 50 && AI_RandLessThan(128)) ADJUST_SCORE(1); @@ -3569,7 +3612,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(5); if (aiData->holdEffects[battlerAtk] == HOLD_EFFECT_LIGHT_CLAY) ADJUST_SCORE(2); - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SCREENER) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SCREENER) ADJUST_SCORE(2); } break; @@ -3611,7 +3654,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score ADJUST_SCORE(5); break; case EFFECT_MIST: - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SCREENER) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SCREENER) ADJUST_SCORE(2); break; case EFFECT_FOCUS_ENERGY: @@ -4070,7 +4113,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score break; case STAT_DEF: case STAT_SPDEF: - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL) ADJUST_SCORE(1); break; } @@ -4697,7 +4740,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))) @@ -4868,7 +4911,7 @@ static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score || gBattleResults.battleTurnCounter != 0) return score; - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING && AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER && CanTargetFaintAi(battlerDef, battlerAtk) && GetMovePriority(battlerAtk, move) == 0) @@ -5001,6 +5044,7 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_FOCUS_PUNCH: case EFFECT_REVENGE: case EFFECT_TEETER_DANCE: + case EFFECT_FILLET_AWAY: if (Random() & 1) ADJUST_SCORE(2); break; @@ -5151,6 +5195,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_CONVERSION_2: case EFFECT_SAFEGUARD: case EFFECT_BELLY_DRUM: + case EFFECT_FILLET_AWAY: ADJUST_SCORE(-2); break; default: @@ -5186,6 +5231,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_HAIL: case EFFECT_SNOWSCAPE: case EFFECT_RAIN_DANCE: + case EFFECT_FILLET_AWAY: ADJUST_SCORE(-2); break; default: diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 7436f7af6d0a..43450089c409 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -38,10 +38,10 @@ static void InitializeSwitchinCandidate(struct Pokemon *mon) static bool32 IsAceMon(u32 battler, u32 monPartyId) { - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_ACE_POKEMON - && !(gBattleStruct->forcedSwitch & gBitTable[battler]) - && monPartyId == CalculateEnemyPartyCount()-1) - return TRUE; + if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON + && !(gBattleStruct->forcedSwitch & gBitTable[battler]) + && monPartyId == CalculateEnemyPartyCount()-1) + return TRUE; return FALSE; } @@ -77,7 +77,7 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult) u16 typeEffectiveness = UQ_4_12(1.0), aiMoveEffect; //baseline typing damage // Only use this if AI_FLAG_SMART_SWITCHING is set for the trainer - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING)) + if (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING)) return FALSE; // Won't bother configuring this for double battles @@ -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) @@ -433,7 +433,7 @@ static bool32 ShouldSwitchIfGameStatePrompt(u32 battler, bool32 emitResult) && monAbility != ABILITY_SOUNDPROOF) switchMon = TRUE; - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING) + if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING) { //Yawn if (gStatuses3[battler] & STATUS3_YAWN @@ -851,7 +851,7 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) static bool32 ShouldSwitchIfEncored(u32 battler, bool32 emitResult) { // Only use this if AI_FLAG_SMART_SWITCHING is set for the trainer - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING)) + if (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING)) return FALSE; // If not Encored or if no good switchin, don't switch @@ -877,7 +877,7 @@ static bool32 AreAttackingStatsLowered(u32 battler, bool32 emitResult) s8 spAttackingStage = gBattleMons[battler].statStages[STAT_SPATK]; // Only use this if AI_FLAG_SMART_SWITCHING is set for the trainer - if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING)) + if (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING)) return FALSE; // Physical attacker @@ -1015,7 +1015,7 @@ bool32 ShouldSwitch(u32 battler, bool32 emitResult) return TRUE; //These Functions can prompt switch to generic pary members - if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING) && (CanMonSurviveHazardSwitchin(battler) == FALSE)) + if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING) && (CanMonSurviveHazardSwitchin(battler) == FALSE)) return FALSE; if (ShouldSwitchIfAllBadMoves(battler, emitResult)) return TRUE; @@ -1939,7 +1939,7 @@ u8 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) // Split ideal mon decision between after previous mon KO'd (prioritize offensive options) and after switching active mon out (prioritize defensive options), and expand the scope of both. // Only use better mon selection if AI_FLAG_SMART_MON_CHOICES is set for the trainer. - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_MON_CHOICES) + if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_MON_CHOICES) { bestMonId = GetBestMonIntegrated(party, firstId, lastId, battler, opposingBattler, battlerIn1, battlerIn2, switchAfterMonKOd); return bestMonId; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 1ad43434424b..aa994689e538 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -361,6 +361,7 @@ static const u16 sEncouragedEncoreEffects[] = EFFECT_WATER_SPORT, EFFECT_DRAGON_DANCE, EFFECT_CAMOUFLAGE, + EFFECT_FILLET_AWAY, }; // Functions @@ -404,7 +405,7 @@ bool32 BattlerHasAi(u32 battlerId) bool32 IsAiBattlerAware(u32 battlerId) { - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_OMNISCIENT) + if (AI_THINKING_STRUCT->aiFlags[battlerId] & AI_FLAG_OMNISCIENT) return TRUE; return BattlerHasAi(battlerId); @@ -709,11 +710,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); @@ -825,6 +829,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; @@ -1290,7 +1295,7 @@ u32 AI_DecideHoldEffectForTurn(u32 battlerId) else holdEffect = GetBattlerHoldEffect(battlerId, FALSE); - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + if (AI_THINKING_STRUCT->aiFlags[battlerId] & AI_FLAG_NEGATE_UNAWARE) return holdEffect; if (gStatuses3[battlerId] & STATUS3_EMBARGO) @@ -1341,7 +1346,7 @@ bool32 AI_IsBattlerGrounded(u32 battlerId) bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move) { - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return FALSE; // AI handicap flag: doesn't understand ability suppression concept if (IsMoldBreakerTypeAbility(atkAbility) || gBattleMoves[move].ignoresTargetAbility) @@ -1352,7 +1357,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move) static inline bool32 AI_WeatherHasEffect(struct AiLogicData *aiData) { - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return TRUE; // AI doesn't understand weather supression (handicap) return aiData->weatherHasEffect; // weather damping abilities are announced @@ -1437,7 +1442,7 @@ bool32 IsHazardMoveEffect(u32 moveEffect) bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility) { - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return FALSE; if (move == MOVE_SKY_DROP @@ -1766,7 +1771,9 @@ u32 CountNegativeStatStages(u32 battlerId) bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4 @@ -1783,7 +1790,9 @@ bool32 ShouldLowerAttack(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 @@ -1800,7 +1809,9 @@ bool32 ShouldLowerDefense(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (!AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) @@ -1815,7 +1826,9 @@ bool32 ShouldLowerSpeed(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4 @@ -1831,7 +1844,9 @@ bool32 ShouldLowerSpAtk(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4 @@ -1847,7 +1862,9 @@ bool32 ShouldLowerSpDef(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (defAbility != ABILITY_CONTRARY @@ -1864,7 +1881,9 @@ bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility) bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility) { - if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) && (AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if (AI_STRIKES_FIRST(battlerAtk, battlerDef, AI_THINKING_STRUCT->moveConsidered) + && (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) + && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return FALSE; // Don't bother lowering stats if can kill enemy. if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE @@ -2015,28 +2034,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) @@ -2046,7 +2046,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; } @@ -2112,6 +2112,7 @@ bool32 IsAttackBoostMoveEffect(u32 effect) case EFFECT_BELLY_DRUM: case EFFECT_BULK_UP: case EFFECT_GROWTH: + case EFFECT_FILLET_AWAY: return TRUE; default: return FALSE; @@ -2969,7 +2970,7 @@ bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move) if (BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->abilities[battlerDef])) return TRUE; // battler is taking secondary damage with low HP - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL) { if (!CanTargetFaintAi(battlerDef, battlerAtk)) return TRUE; // attacker goes first and opponent can't kill us @@ -3553,7 +3554,7 @@ void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) if (AI_DATA->hpPercents[battlerAtk] < 80 && AI_RandLessThan(128)) return; - if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; // Damaging moves would get a score boost from AI_TryToFaint or PreferStrongestMove so we don't consider them here switch (statId) @@ -3627,8 +3628,8 @@ void IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId, s32 *score) void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) return; if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove) && AI_DATA->hpPercents[battlerDef] > 20) @@ -3636,7 +3637,7 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) if (!HasDamagingMove(battlerDef)) ADJUST_SCORE_PTR(2); - if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT)) + if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT)) ADJUST_SCORE_PTR(1); // stall tactic if (HasMoveEffect(battlerAtk, EFFECT_VENOSHOCK) @@ -3651,8 +3652,8 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) return; if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)) @@ -3671,8 +3672,8 @@ void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) return; if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove)) @@ -3693,8 +3694,8 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) return; if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove)) @@ -3712,8 +3713,8 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) - || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_CONFUSION || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) + if (((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_CONFUSION || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS) return; if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove) @@ -3731,7 +3732,7 @@ void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score) { - if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) + if ((AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0)) return; if (AI_CanGiveFrostbite(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)) diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 188ec915d661..abcdd44c357d 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6575,12 +6575,14 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId) SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct)); SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo)); + SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp); SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp); - SWAP(gTransformedOtIds[battlerAtk], gTransformedOtIds[battlerPartner], temp); + SWAP(gTransformedShininess[battlerAtk], gTransformedShininess[battlerPartner], temp); SWAP(gStatuses3[battlerAtk], gStatuses3[battlerPartner], temp); SWAP(gStatuses4[battlerAtk], gStatuses4[battlerPartner], temp); SWAP(gBattleStruct->chosenMovePositions[battlerAtk], gBattleStruct->chosenMovePositions[battlerPartner], temp); SWAP(gChosenMoveByBattler[battlerAtk], gChosenMoveByBattler[battlerPartner], temp); + SWAP(gLockedMoves[battlerAtk], gLockedMoves[battlerPartner], temp); SWAP(gBattleStruct->moveTarget[battlerAtk], gBattleStruct->moveTarget[battlerPartner], temp); SWAP(gMoveSelectionCursor[battlerAtk], gMoveSelectionCursor[battlerPartner], temp); // Swap turn order, so that all the battlers take action @@ -6688,6 +6690,12 @@ void AnimTask_AllySwitchAttacker(u8 taskId) PrepareDoubleTeamAnim(taskId, ANIM_ATTACKER, TRUE); gSprites[gBattlerSpriteIds[gBattlerAttacker]].invisible = TRUE; gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattlerAttacker)]].invisible = TRUE; + // Edge case: Partner's sprite is invisible(i.e. after using Dig). + if (gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(gBattlerAttacker)].invisible) + { + gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(gBattlerAttacker)].invisible = FALSE; + gBattleSpritesDataPtr->battlerData[gBattlerAttacker].invisible = TRUE; + } } void AnimTask_AllySwitchPartner(u8 taskId) diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c index 2c8572cc8ca2..26fb3ef2ec2d 100644 --- a/src/battle_anim_effects_3.c +++ b/src/battle_anim_effects_3.c @@ -3255,9 +3255,8 @@ static void AnimReversalOrb_Step(struct Sprite *sprite) // Copies the target mon's sprite, and makes a white silhouette that shrinks away. void AnimTask_RolePlaySilhouette(u8 taskId) { - bool8 isBackPic; + bool8 isBackPic, isShiny; u32 personality; - u32 otId; u16 species; s16 xOffset; u32 priority; @@ -3269,7 +3268,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId) { isBackPic = TRUE; personality = gContestResources->moveAnim->targetPersonality; - otId = gContestResources->moveAnim->otId; + isShiny = gContestResources->moveAnim->targetIsShiny; species = gContestResources->moveAnim->targetSpecies; xOffset = 20; priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); @@ -3280,7 +3279,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId) { isBackPic = FALSE; personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_IS_SHINY); if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE) { if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) @@ -3300,7 +3299,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId) { isBackPic = TRUE; personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_IS_SHINY); if (gBattleSpritesDataPtr->battlerData[gBattleAnimTarget].transformSpecies == SPECIES_NONE) { if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) @@ -3320,7 +3319,7 @@ void AnimTask_RolePlaySilhouette(u8 taskId) coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); - spriteId = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId, gBattleAnimTarget); + spriteId = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, isShiny, gBattleAnimTarget); gSprites[spriteId].oam.priority = priority; gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND; @@ -5162,10 +5161,9 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId) { u8 spriteId, spriteId2; int personality; - int otId; u16 species; u8 subpriority; - bool8 isBackPic; + bool8 isBackPic, isShiny; s16 x; switch (gTasks[taskId].data[0]) @@ -5190,7 +5188,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId) if (IsContest()) { personality = gContestResources->moveAnim->personality; - otId = gContestResources->moveAnim->otId; + isShiny = gContestResources->moveAnim->isShiny; species = gContestResources->moveAnim->species; subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker); isBackPic = FALSE; @@ -5201,7 +5199,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId) if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) { personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_IS_SHINY); if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE) species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); else @@ -5214,7 +5212,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId) else { personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_IS_SHINY); if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies == SPECIES_NONE) species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); else @@ -5226,7 +5224,7 @@ void AnimTask_SnatchOpposingMonMove(u8 taskId) } } - spriteId2 = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId, gBattleAnimAttacker); + spriteId2 = CreateAdditionalMonSpriteForMoveAnim(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, isShiny, gBattleAnimAttacker); if (gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies != SPECIES_NONE) BlendPalette(OBJ_PLTT_ID(gSprites[spriteId2].oam.paletteNum), 16, 6, RGB_WHITE); 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 78e1a0a445e8..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,8 +2052,8 @@ u8 GetBattlerSpriteBGPriorityRank(u8 battlerId) return 1; } -// Create pokemon 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, u32 trainerId, u32 battlerId) +// 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; u16 sheet = LoadSpriteSheet(&sSpriteSheets_MoveEffectMons[id]); @@ -2063,7 +2063,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 gMonSpritesGfxPtr->buffer = AllocZeroed(MON_PIC_SIZE * MAX_MON_PIC_FRAMES); if (!isBackpic) { - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP); LoadSpecialPokePic(gMonSpritesGfxPtr->buffer, species, personality, @@ -2071,7 +2071,7 @@ u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 } else { - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(palette), PLTT_SIZE_4BPP); LoadSpecialPokePic(gMonSpritesGfxPtr->buffer, species, personality, diff --git a/src/battle_anim_throw.c b/src/battle_anim_throw.c index 4d2873a92afa..6a23807a133a 100644 --- a/src/battle_anim_throw.c +++ b/src/battle_anim_throw.c @@ -2481,26 +2481,17 @@ void AnimTask_SetTargetToEffectBattler(u8 taskId) void TryShinyAnimation(u8 battler, struct Pokemon *mon) { bool8 isShiny; - u32 otId, personality; - u32 shinyValue; u8 taskCirc, taskDgnl; struct Pokemon* illusionMon; - isShiny = FALSE; + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = TRUE; illusionMon = GetIllusionMonPtr(battler); if (illusionMon != NULL) mon = illusionMon; - otId = GetMonData(mon, MON_DATA_OT_ID); - personality = GetMonData(mon, MON_DATA_PERSONALITY); - if (IsBattlerSpriteVisible(battler) && IsValidForBattle(mon)) { - shinyValue = GET_SHINY_VALUE(otId, personality); - if (shinyValue < SHINY_ODDS) - isShiny = TRUE; - if (isShiny) { if (GetSpriteTileStartByTag(ANIM_TAG_GOLD_STARS) == 0xFFFF) diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 649240ce34da..7ffcd5ae2c7d 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -679,7 +679,7 @@ static void OpponentHandleChoosePokemon(u32 battler) if (IsValidForBattle(&gEnemyParty[chosenMonId]) && chosenMonId != gBattlerPartyIndexes[battler1] && chosenMonId != gBattlerPartyIndexes[battler2] - && (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_ACE_POKEMON) + && (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON) || chosenMonId != CalculateEnemyPartyCount() - 1 || CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle)) { 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_controllers.c b/src/battle_controllers.c index 632d7e50d848..d6389f02ccdf 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -2649,7 +2649,7 @@ void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData) gWeatherMoveAnim = gBattleResources->bufferA[battler][12] | (gBattleResources->bufferA[battler][13] << 8); gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[battler][16]; gTransformedPersonalities[battler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[battler] = gAnimDisableStructPtr->transformedMonOtId; + gTransformedShininess[battler] = gAnimDisableStructPtr->transformedMonShininess; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; gBattlerControllerFuncs[battler] = Controller_DoMoveAnimation; if (updateTvData) diff --git a/src/battle_debug.c b/src/battle_debug.c index 3fca57e38ffd..8e4046b56589 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -801,7 +801,7 @@ static void Task_ShowAiPoints(u8 taskId) } } data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species, - gBattleMons[data->aiBattlerId].otId, + gBattleMons[data->aiBattlerId].isShiny, gBattleMons[data->aiBattlerId].personality, TRUE, 39, 130, 15, TAG_NONE); @@ -864,7 +864,7 @@ static void PutAiInfoText(struct BattleDebugMenu *data) u16 holdEffect = AI_DATA->holdEffects[i]; u16 item = AI_DATA->items[i]; u8 x = (i == B_POSITION_PLAYER_LEFT) ? 83 + (i) * 75 : 83 + (i-1) * 75; - AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, gAbilityNames[ability], x, 0, 0, NULL); + AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, gAbilities[ability].name, x, 0, 0, NULL); AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, ItemId_GetName(item), x, 15, 0, NULL); AddTextPrinterParameterized(data->aiMovesWindowId, FONT_SMALL, GetHoldEffectName(holdEffect), x, 30, 0, NULL); } @@ -897,7 +897,7 @@ static void PutAiPartyText(struct BattleDebugMenu *data) AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 0, 0, NULL, 0, 0); } - txtPtr = StringCopyN(text, gAbilityNames[aiMons[i].ability], 7); // The screen is too small to fit the whole string, so we need to drop the last letters. + txtPtr = StringCopyN(text, gAbilities[aiMons[i].ability].name, 7); // The screen is too small to fit the whole string, so we need to drop the last letters. *txtPtr = EOS; AddTextPrinterParameterized5(data->aiMovesWindowId, FONT_SMALL_NARROW, text, i * 41, 15, 0, NULL, 0, 0); @@ -958,7 +958,7 @@ static void Task_ShowAiKnowledge(u8 taskId) } } data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species, - gBattleMons[data->aiBattlerId].otId, + gBattleMons[data->aiBattlerId].isShiny, gBattleMons[data->aiBattlerId].personality, TRUE, 39, 130, 15, TAG_NONE); @@ -1433,7 +1433,7 @@ static void PrintSecondaryEntries(struct BattleDebugMenu *data) } break; case LIST_ITEM_ABILITY: - PadString(gAbilityNames[gBattleMons[data->battlerId].ability], text); + PadString(gAbilities[gBattleMons[data->battlerId].ability].name, text); printer.currentY = printer.y = sSecondaryListTemplate.upText_Y; AddTextPrinter(&printer, 0, NULL); break; @@ -1901,8 +1901,8 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) data->modifyArrows.typeOfVal = VAL_BITFIELD_32; goto CASE_ITEM_STATUS; case LIST_ITEM_AI: - data->modifyArrows.modifiedValPtr = &gBattleResources->ai->aiFlags; - data->modifyArrows.currValue = GetBitfieldValue(gBattleResources->ai->aiFlags, data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount); + data->modifyArrows.modifiedValPtr = &gBattleResources->ai->aiFlags[data->battlerId]; + data->modifyArrows.currValue = GetBitfieldValue(gBattleResources->ai->aiFlags[data->battlerId], data->bitfield[data->currentSecondaryListItemId].currBit, data->bitfield[data->currentSecondaryListItemId].bitsCount); data->modifyArrows.typeOfVal = VAL_BITFIELD_32; goto CASE_ITEM_STATUS; CASE_ITEM_STATUS: diff --git a/src/battle_dome.c b/src/battle_dome.c index 05b8ebec4a26..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: @@ -4152,6 +4152,7 @@ static bool32 IsDomeComboMoveEffect(u32 effect) case EFFECT_CHARGE: case EFFECT_BULK_UP: case EFFECT_ATTACK_ACCURACY_UP: + case EFFECT_FILLET_AWAY: // Others case EFFECT_FOCUS_ENERGY: case EFFECT_LOCK_ON: @@ -4343,7 +4344,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) move = gSaveBlock2Ptr->frontier.domePlayerPartyData[i].moves[j]; else move = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].moves[j]; - + switch (k) { case MOVE_POINTS_COMBO: @@ -4359,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; @@ -4746,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) @@ -4786,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) @@ -5137,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_dynamax.c b/src/battle_dynamax.c index a44bb3aeb903..bf223e50023d 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -149,8 +149,8 @@ bool32 CanDynamax(u16 battlerId) // Returns whether a battler is transformed into a Gigantamax form. bool32 IsGigantamaxed(u16 battlerId) { - // TODO: Incorporate Gigantamax factor. - if ((gSpeciesInfo[gBattleMons[battlerId].species].isGigantamax)) + struct Pokemon *mon = &GetSideParty(GetBattlerSide(battlerId))[gBattlerPartyIndexes[battlerId]]; + if ((gSpeciesInfo[gBattleMons[battlerId].species].isGigantamax) && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR)) return TRUE; return FALSE; } @@ -162,9 +162,9 @@ void ApplyDynamaxHPMultiplier(u32 battler, struct Pokemon* mon) return; else { - u16 mult = UQ_4_12(1.5); // placeholder - u16 hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult) + UQ_4_12_ROUND); - u16 maxHP = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_MAX_HP) * mult) + UQ_4_12_ROUND); + u32 scale = 150 + 5 * GetMonData(mon, MON_DATA_DYNAMAX_LEVEL); + u32 hp = (GetMonData(mon, MON_DATA_HP) * scale + 99) / 100; + u32 maxHP = (GetMonData(mon, MON_DATA_MAX_HP) * scale + 99) / 100; SetMonData(mon, MON_DATA_HP, &hp); SetMonData(mon, MON_DATA_MAX_HP, &maxHP); } 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 66ff6bcb0301..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) @@ -2017,9 +2017,9 @@ static void Select_CreateMonSprite(void) struct Pokemon *mon = &sFactorySelectScreen->mons[monId].monData; u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); - u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); - sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE); + sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE); gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0; @@ -2035,7 +2035,8 @@ static void Select_ReshowMonSprite(void) { struct Pokemon *mon; u16 species; - u32 personality, otId; + u32 personality; + bool8 isShiny; sFactorySelectScreen->monPics[1].bgSpriteId = CreateSprite(&sSpriteTemplate_Select_MonPicBgAnim, 120, 64, 1); StartSpriteAffineAnim(&gSprites[sFactorySelectScreen->monPics[1].bgSpriteId], 2); @@ -2043,9 +2044,9 @@ static void Select_ReshowMonSprite(void) mon = &sFactorySelectScreen->mons[sFactorySelectScreen->cursorPos].monData; species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); - otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); - sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE); + sFactorySelectScreen->monPics[1].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE); gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[1].monSpriteId].centerToCornerVecY = 0; @@ -2065,9 +2066,9 @@ static void Select_CreateChosenMonsSprites(void) struct Pokemon *mon = &sFactorySelectScreen->mons[j].monData; u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); - u32 otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); - sFactorySelectScreen->monPics[i].monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, (i * 72) + 16, 32, i + 13, TAG_NONE); + sFactorySelectScreen->monPics[i].monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, (i * 72) + 16, 32, i + 13, TAG_NONE); gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySelectScreen->monPics[i].monSpriteId].centerToCornerVecY = 0; break; @@ -2415,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++; @@ -2630,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) @@ -2645,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(); @@ -3553,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; @@ -4076,7 +4077,8 @@ static void Swap_ShowSummaryMonSprite(void) { struct Pokemon *mon; u16 species; - u32 personality, otId; + u32 personality; + bool8 isShiny; sFactorySwapScreen->monPic.bgSpriteId = CreateSprite(&sSpriteTemplate_Swap_MonPicBgAnim, 120, 64, 1); StartSpriteAffineAnim(&gSprites[sFactorySwapScreen->monPic.bgSpriteId], 2); @@ -4084,13 +4086,9 @@ static void Swap_ShowSummaryMonSprite(void) mon = &gPlayerParty[sFactorySwapScreen->cursorPos]; species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); - otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); -#ifdef BUGFIX - sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE); -#else - sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, personality, otId, TRUE, 88, 32, 15, TAG_NONE); -#endif + sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE); gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0; @@ -4295,7 +4293,8 @@ static void Swap_CreateMonSprite(void) { struct Pokemon *mon; u16 species; - u32 personality, otId; + u32 personality; + bool8 isShiny; if (!sFactorySwapScreen->inEnemyScreen) mon = &gPlayerParty[sFactorySwapScreen->cursorPos]; @@ -4304,9 +4303,9 @@ static void Swap_CreateMonSprite(void) species = GetMonData(mon, MON_DATA_SPECIES, NULL); personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); - otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); - sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, otId, personality, TRUE, 88, 32, 15, TAG_NONE); + sFactorySwapScreen->monPic.monSpriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, 88, 32, 15, TAG_NONE); gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecX = 0; gSprites[sFactorySwapScreen->monPic.monSpriteId].centerToCornerVecY = 0; diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index b38ccf495bfa..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]; @@ -570,7 +570,7 @@ bool8 IsBattleSEPlaying(u8 battler) void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler) { - u32 monsPersonality, currentPersonality, otId, currentOtId, species, paletteOffset, position; + u32 monsPersonality, currentPersonality, isShiny, species, paletteOffset, position; const void *lzPaletteData; struct Pokemon *illusionMon = GetIllusionMonPtr(battler); if (illusionMon != NULL) @@ -580,13 +580,12 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler) return; monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY); - otId = GetMonData(mon, MON_DATA_OT_ID); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE) { species = GetMonData(mon, MON_DATA_SPECIES); currentPersonality = monsPersonality; - currentOtId = otId; } else { @@ -594,12 +593,10 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler) if (B_TRANSFORM_SHINY >= GEN_4) { currentPersonality = gTransformedPersonalities[battler]; - currentOtId = gTransformedOtIds[battler]; } else { currentPersonality = monsPersonality; - currentOtId = otId; } } @@ -622,7 +619,7 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler) if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE) lzPaletteData = GetMonFrontSpritePal(mon); else - lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, currentOtId, currentPersonality); + lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, currentPersonality); LZDecompressWram(lzPaletteData, gDecompressionBuffer); LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP); @@ -867,7 +864,8 @@ void CopyBattleSpriteInvisibility(u8 battler) void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool8 trackEnemyPersonality) { - u32 personalityValue, otId, position, paletteOffset, targetSpecies; + u32 personalityValue, position, paletteOffset, targetSpecies; + bool8 isShiny; const void *lzPaletteData, *src; void *dst; @@ -876,7 +874,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo position = B_POSITION_PLAYER_LEFT; targetSpecies = gContestResources->moveAnim->targetSpecies; personalityValue = gContestResources->moveAnim->personality; - otId = gContestResources->moveAnim->otId; + isShiny = gContestResources->moveAnim->isShiny; HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[position], @@ -897,14 +895,13 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality) { personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID); + isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); } else { personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID); + isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); } - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID); HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[position], @@ -916,13 +913,12 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality) { personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID); - + isShiny = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); } else { personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_OT_ID); + isShiny = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_IS_SHINY); } HandleLoadSpecialPokePic(TRUE, @@ -935,7 +931,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo dst = (void *)(OBJ_VRAM0 + gSprites[gBattlerSpriteIds[battlerAtk]].oam.tileNum * 32); DmaCopy32(3, src, dst, MON_PIC_SIZE); paletteOffset = OBJ_PLTT_ID(battlerAtk); - lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, otId, personalityValue); + lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue); LZDecompressWram(lzPaletteData, gDecompressionBuffer); LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP); diff --git a/src/battle_interface.c b/src/battle_interface.c index b07cb3ee0784..3357fd9939d5 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -3113,7 +3113,7 @@ static void PrintBattlerOnAbilityPopUp(u8 battlerId, u8 spriteId1, u8 spriteId2) static void PrintAbilityOnAbilityPopUp(u32 ability, u8 spriteId1, u8 spriteId2) { - PrintOnAbilityPopUp(gAbilityNames[ability], + PrintOnAbilityPopUp(gAbilities[ability].name, (void*)(OBJ_VRAM0) + (gSprites[spriteId1].oam.tileNum * 32) + 256, (void*)(OBJ_VRAM0) + (gSprites[spriteId2].oam.tileNum * 32) + 256, 5, 12, diff --git a/src/battle_main.c b/src/battle_main.c index 6a1d6eb6ab72..951766adcdc6 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -214,7 +214,7 @@ EWRAM_DATA u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u8 gBattlerInMenuId = 0; EWRAM_DATA bool8 gDoingBattleAnim = FALSE; EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u32 gTransformedOtIds[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA bool8 gTransformedShininess[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u8 gPlayerDpadHoldFrames = 0; EWRAM_DATA struct BattleSpriteData *gBattleSpritesDataPtr = NULL; EWRAM_DATA struct MonSpritesGfx *gMonSpritesGfxPtr = NULL; @@ -409,8 +409,6 @@ static const u16 sTrainerBallTable[TRAINER_CLASS_COUNT] = }; #endif -#include "data/text/abilities.h" - static void (* const sTurnActionsFuncsTable[])(void) = { [B_ACTION_USE_MOVE] = HandleAction_UseMove, @@ -2018,6 +2016,21 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer { SetMonData(&party[i], MON_DATA_NICKNAME, partyData[i].nickname); } + if (partyData[i].isShiny) + { + u32 data = TRUE; + SetMonData(&party[i], MON_DATA_IS_SHINY, &data); + } + if (partyData[i].dynamaxLevel > 0) + { + u32 data = partyData[i].dynamaxLevel; + SetMonData(&party[i], MON_DATA_DYNAMAX_LEVEL, &data); + } + if (partyData[i].gigantamaxFactor) + { + u32 data = partyData[i].gigantamaxFactor; + SetMonData(&party[i], MON_DATA_GIGANTAMAX_FACTOR, &data); + } CalculateMonStats(&party[i]); #if B_TRAINER_CLASS_POKE_BALLS >= GEN_7 @@ -3250,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; @@ -4714,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) @@ -5654,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 35ff5379ec3e..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; @@ -3407,19 +3410,19 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) } break; case B_TXT_LAST_ABILITY: // last used ability - toCpy = gAbilityNames[gLastUsedAbility]; + toCpy = gAbilities[gLastUsedAbility].name; break; case B_TXT_ATK_ABILITY: // attacker ability - toCpy = gAbilityNames[sBattlerAbilities[gBattlerAttacker]]; + toCpy = gAbilities[sBattlerAbilities[gBattlerAttacker]].name; break; case B_TXT_DEF_ABILITY: // target ability - toCpy = gAbilityNames[sBattlerAbilities[gBattlerTarget]]; + toCpy = gAbilities[sBattlerAbilities[gBattlerTarget]].name; break; case B_TXT_SCR_ACTIVE_ABILITY: // scripting active ability - toCpy = gAbilityNames[sBattlerAbilities[gBattleScripting.battler]]; + toCpy = gAbilities[sBattlerAbilities[gBattleScripting.battler]].name; break; case B_TXT_EFF_ABILITY: // effect battler ability - toCpy = gAbilityNames[sBattlerAbilities[gEffectBattler]]; + toCpy = gAbilities[sBattlerAbilities[gEffectBattler]].name; break; case B_TXT_TRAINER1_CLASS: // trainer class name toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A); @@ -3781,7 +3784,7 @@ void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst) srcID += 2; break; case B_BUFF_ABILITY: // ability names - StringAppend(dst, gAbilityNames[T1_READ_16(&src[srcID + 1])]); + StringAppend(dst, gAbilities[T1_READ_16(&src[srcID + 1])].name); srcID += 3; break; case B_BUFF_ITEM: // item name diff --git a/src/battle_pike.c b/src/battle_pike.c index 0692b680630d..3869531d2090 100644 --- a/src/battle_pike.c +++ b/src/battle_pike.c @@ -886,14 +886,8 @@ static bool8 TryInflictRandomStatus(void) for (i = 0; i < FRONTIER_PARTY_SIZE; i++) indices[i] = i; - for (j = 0; j < 10; j++) - { - u8 temp, id; - i = Random() % FRONTIER_PARTY_SIZE; - id = Random() % FRONTIER_PARTY_SIZE; - SWAP(indices[i], indices[id], temp); - } + Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0])); if (gSaveBlock2Ptr->frontier.curChallengeBattleNum <= 4) count = 1; @@ -1265,7 +1259,7 @@ static void Task_DoStatusInflictionScreenFlash(u8 taskId) static void TryHealMons(u8 healCount) { - u8 j, i, k; + u8 j, i; u8 indices[FRONTIER_PARTY_SIZE]; if (healCount == 0) @@ -1274,17 +1268,9 @@ 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, - // and determined by performing 10 random swaps to this index array. - for (k = 0; k < 10; k++) - { - u8 temp; - - i = Random() % FRONTIER_PARTY_SIZE; - j = Random() % FRONTIER_PARTY_SIZE; - SWAP(indices[i], indices[j], temp); - } + Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0])); for (i = 0; i < FRONTIER_PARTY_SIZE; i++) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 0272aa4108db..efa31669e17e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -543,7 +543,7 @@ static void Cmd_setsafeguard(void); static void Cmd_magnitudedamagecalculation(void); static void Cmd_jumpifnopursuitswitchdmg(void); static void Cmd_setsunny(void); -static void Cmd_maxattackhalvehp(void); +static void Cmd_halvehp(void); static void Cmd_copyfoestats(void); static void Cmd_rapidspinfree(void); static void Cmd_setdefensecurlbit(void); @@ -802,7 +802,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_magnitudedamagecalculation, //0xB9 Cmd_jumpifnopursuitswitchdmg, //0xBA Cmd_setsunny, //0xBB - Cmd_maxattackhalvehp, //0xBC + Cmd_halvehp, //0xBC Cmd_copyfoestats, //0xBD Cmd_rapidspinfree, //0xBE Cmd_setdefensecurlbit, //0xBF @@ -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; @@ -10250,12 +10264,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 +10733,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 +11820,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]; } @@ -12308,7 +12321,7 @@ static void Cmd_transformdataexecution(void) gDisableStructs[gBattlerAttacker].disabledMove = MOVE_NONE; gDisableStructs[gBattlerAttacker].disableTimer = 0; gDisableStructs[gBattlerAttacker].transformedMonPersonality = gBattleMons[gBattlerTarget].personality; - gDisableStructs[gBattlerAttacker].transformedMonOtId = gBattleMons[gBattlerTarget].otId; + gDisableStructs[gBattlerAttacker].transformedMonShininess = gBattleMons[gBattlerTarget].isShiny; gDisableStructs[gBattlerAttacker].mimickedMoves = 0; gDisableStructs[gBattlerAttacker].usedMoves = 0; @@ -12357,7 +12370,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; @@ -12693,10 +12706,8 @@ static void Cmd_copymovepermanently(void) gChosenMove = MOVE_UNAVAILABLE; if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) - && gLastPrintedMoves[gBattlerTarget] != MOVE_STRUGGLE - && gLastPrintedMoves[gBattlerTarget] != MOVE_NONE && gLastPrintedMoves[gBattlerTarget] != MOVE_UNAVAILABLE - && gLastPrintedMoves[gBattlerTarget] != MOVE_SKETCH) + && !gBattleMoves[gLastPrintedMoves[gBattlerTarget]].sketchBanned) { s32 i; @@ -13324,8 +13335,8 @@ static void Cmd_setsunny(void) gBattlescriptCurrInstr = cmd->nextInstr; } -// Belly Drum -static void Cmd_maxattackhalvehp(void) +// Belly Drum, Fillet Away +static void Cmd_halvehp(void) { CMD_ARGS(const u8 *failInstr); @@ -13334,11 +13345,8 @@ static void Cmd_maxattackhalvehp(void) if (!(GetNonDynamaxMaxHP(gBattlerAttacker) / 2)) halfHp = 1; - // Belly Drum fails if the user's current HP is less than half its maximum, or if the user's Attack is already at +6 (even if the user has Contrary). - if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] < MAX_STAT_STAGE - && gBattleMons[gBattlerAttacker].hp > halfHp) + if (gBattleMons[gBattlerAttacker].hp > halfHp) { - gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = MAX_STAT_STAGE; gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -13858,7 +13866,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) @@ -15171,10 +15179,11 @@ static void Cmd_displaydexinfo(void) case 1: if (!gPaletteFade.active) { + struct Pokemon *mon = &gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]]; FreeAllWindowBuffers(); gBattleCommunication[TASK_ID] = DisplayCaughtMonDexPage(species, - gBattleMons[GetCatchingBattler()].otId, - gBattleMons[GetCatchingBattler()].personality); + GetMonData(mon, MON_DATA_IS_SHINY), + GetMonData(mon, MON_DATA_PERSONALITY)); gBattleCommunication[0]++; } break; @@ -16579,3 +16588,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 6dba9a63eda4..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; @@ -2990,21 +2990,17 @@ static void FillPartnerParty(u16 trainerId) else otID = ((firstIdPart % 72) * 1000) + ((secondIdPart % 23) * 10) + (thirdIdPart % 37) % 65536; - do - { - personality = Random32(); - } while (IsShinyOtIdPersonality(otID, personality)); - + personality = Random32(); if (partyData[i].gender == TRAINER_MON_MALE) personality = (personality & 0xFFFFFF00) | GeneratePersonalityForGender(MON_MALE, partyData[i].species); else if (partyData[i].gender == TRAINER_MON_FEMALE) personality = (personality & 0xFFFFFF00) | GeneratePersonalityForGender(MON_FEMALE, partyData[i].species); if (partyData[i].nature != 0) ModifyPersonalityForNature(&personality, partyData[i].nature - 1); - if (partyData[i].isShiny) - otID ^= GET_SHINY_VALUE(otID, personality) << 16; CreateMon(&gPlayerParty[i + 3], partyData[i].species, partyData[i].lvl, 0, TRUE, personality, OT_ID_PRESET, otID); + j = partyData[i].isShiny; + SetMonData(&gPlayerParty[i + 3], MON_DATA_IS_SHINY, &j); SetMonData(&gPlayerParty[i + 3], MON_DATA_HELD_ITEM, &partyData[i].heldItem); CustomTrainerPartyAssignMoves(&gPlayerParty[i + 3], &partyData[i]); @@ -3462,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) @@ -3481,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++) { @@ -3493,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, @@ -3503,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); @@ -3514,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 da42b4001039..86e616140ad8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2870,7 +2870,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 +2959,7 @@ u8 DoBattlerEndTurnEffects(void) } if (gBattlerAttacker != gBattlersCount) { - effect = 2; // a pokemon was awaken + effect = 2; // a Pokémon was awaken break; } else @@ -3023,7 +3023,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 +3040,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 +3429,8 @@ bool32 HandleFaintedMonActions(void) && gCurrentTurnActionNumber != gBattlersCount) { gAbsentBattlerFlags |= gBitTable[gBattlerFainted]; - return FALSE; + if (gBattleStruct->faintedActionsState != 1) + return FALSE; } break; case 3: @@ -4368,7 +4369,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 +4378,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 +4793,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 +5119,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 +5141,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++; } @@ -6142,7 +6146,7 @@ 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); @@ -8492,6 +8496,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 +9004,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 @@ -10555,6 +10565,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method) u16 targetSpecies = SPECIES_NONE; u16 species = gBattleMons[battler].species; const struct FormChange *formChanges = GetSpeciesFormChanges(species); + struct Pokemon *mon = &GetBattlerParty(battler)[gBattlerPartyIndexes[battler]]; u16 heldItem; if (formChanges != NULL) @@ -10602,8 +10613,8 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method) } break; case FORM_CHANGE_BATTLE_GIGANTAMAX: - // TODO: check Gigantamax factor - targetSpecies = formChanges[i].targetSpecies; + if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR)) + targetSpecies = formChanges[i].targetSpecies; break; case FORM_CHANGE_BATTLE_WEATHER: // Check if there is a required ability and if the battler's ability does not match it 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 d4cc73677cc4..e0c5969a0609 100644 --- a/src/contest.c +++ b/src/contest.c @@ -98,7 +98,7 @@ static void PrintContestantMonName(u8); static void PrintContestantMonNameWithColor(u8, u8); static u8 CreateJudgeSprite(void); static u8 CreateJudgeSpeechBubbleSprite(void); -static u8 CreateContestantSprite(u16, u32, u32, u32); +static u8 CreateContestantSprite(u16, bool8, u32, u32); static void PrintContestMoveDescription(u16); static u16 SanitizeSpecies(u16); static void ContestClearGeneralTextWindow(void); @@ -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, @@ -1781,7 +1781,7 @@ static void Task_DoAppeals(u8 taskId) SetMoveAnimAttackerData(eContest.currentContestant); spriteId = CreateContestantSprite( gContestMons[eContest.currentContestant].species, - gContestMons[eContest.currentContestant].otId, + gContestMons[eContest.currentContestant].isShiny, gContestMons[eContest.currentContestant].personality, eContest.currentContestant); gSprites[spriteId].x2 = 120; @@ -2811,6 +2811,7 @@ void CreateContestMonFromParty(u8 partyIndex) gContestMons[gContestPlayerMonIndex].moves[3] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE4); gContestMons[gContestPlayerMonIndex].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY); gContestMons[gContestPlayerMonIndex].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID); + gContestMons[gContestPlayerMonIndex].isShiny = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_SHINY); heldItem = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM); cool = gContestMons[gContestPlayerMonIndex].cool; @@ -3114,14 +3115,14 @@ static u8 CreateJudgeSpeechBubbleSprite(void) return spriteId; } -static u8 CreateContestantSprite(u16 species, u32 otId, u32 personality, u32 index) +static u8 CreateContestantSprite(u16 species, bool8 isShiny, u32 personality, u32 index) { u8 spriteId; species = SanitizeSpecies(species); HandleLoadSpecialPokePic(FALSE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_PLAYER_LEFT], species, personality); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_PLAYER_LEFT); spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x70, GetBattlerSpriteFinal_Y(2, species, FALSE), 30); @@ -3428,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++) @@ -4584,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) { @@ -5354,6 +5355,7 @@ static void SetMoveAnimAttackerData(u8 contestant) gContestResources->moveAnim->species = SanitizeSpecies(gContestMons[contestant].species); gContestResources->moveAnim->personality = gContestMons[contestant].personality; gContestResources->moveAnim->otId = gContestMons[contestant].otId; + gContestResources->moveAnim->isShiny = gContestMons[contestant].isShiny; } static void CreateInvisibleBattleTargetSprite(void) @@ -5565,6 +5567,7 @@ bool8 SaveContestWinner(u8 rank) { // Set the most recent winner so the artist can show the player their painting gCurContestWinner.personality = gContestMons[i].personality; + gCurContestWinner.isShiny = gContestMons[i].isShiny; gCurContestWinner.trainerId = gContestMons[i].otId; gCurContestWinner.species = gContestMons[i].species; StringCopy(gCurContestWinner.monName, gContestMons[i].nickname); diff --git a/src/contest_painting.c b/src/contest_painting.c index 00bacb5f484d..529330a5228f 100644 --- a/src/contest_painting.c +++ b/src/contest_painting.c @@ -363,7 +363,7 @@ static void VBlankCB_ContestPainting(void) static void InitContestMonPixels(u16 species, bool8 backPic) { - const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gContestPaintingWinner->trainerId, gContestPaintingWinner->personality); + const void *pal = GetMonSpritePalFromSpeciesAndPersonality(species, gContestPaintingWinner->isShiny, gContestPaintingWinner->personality); LZDecompressVram(pal, gContestPaintingMonPalette); if (!backPic) { diff --git a/src/contest_util.c b/src/contest_util.c index 32588a8c00dd..7de492303722 100644 --- a/src/contest_util.c +++ b/src/contest_util.c @@ -879,7 +879,7 @@ static void Task_ShowWinnerMonBanner(u8 taskId) int i; u8 spriteId; u16 species; - u32 otId; + bool8 isShiny; u32 personality; switch (gTasks[taskId].tState) @@ -891,13 +891,13 @@ static void Task_ShowWinnerMonBanner(u8 taskId) GET_CONTEST_WINNER_ID(i); species = gContestMons[i].species; personality = gContestMons[i].personality; - otId = gContestMons[i].otId; + isShiny = gContestMons[i].isShiny; HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality); - LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species); + LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species); SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT); gMultiuseSpriteTemplate.paletteTag = species; spriteId = CreateSprite(&gMultiuseSpriteTemplate, DISPLAY_WIDTH + 32, DISPLAY_HEIGHT / 2, 10); @@ -2552,11 +2552,12 @@ bool8 IsContestDebugActive(void) void ShowContestEntryMonPic(void) { - u32 personality, otId; + u32 personality; u16 species; u8 spriteId; u8 taskId; u8 left, top; + bool32 isShiny; if (FindTaskIdByFunc(Task_ShowContestEntryMonPic) == TASK_NONE) { @@ -2565,13 +2566,13 @@ void ShowContestEntryMonPic(void) top = 3; species = gContestMons[gSpecialVar_0x8006].species; personality = gContestMons[gSpecialVar_0x8006].personality; - otId = gContestMons[gSpecialVar_0x8006].otId; + isShiny = gContestMons[gSpecialVar_0x8006].isShiny; taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50); gTasks[taskId].data[0] = 0; gTasks[taskId].data[1] = species; HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality); - LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species); + LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species); SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT); gMultiuseSpriteTemplate.paletteTag = species; spriteId = CreateSprite(&gMultiuseSpriteTemplate, (left + 1) * 8 + 32, (top * 8) + 40, 0); 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/data/abilities.h b/src/data/abilities.h new file mode 100644 index 000000000000..2ff80f3ab371 --- /dev/null +++ b/src/data/abilities.h @@ -0,0 +1,2068 @@ +const struct Ability gAbilities[ABILITIES_COUNT] = +{ + [ABILITY_NONE] = + { + .name = _("-------"), + .description = COMPOUND_STRING("No special ability."), + }, + + [ABILITY_STENCH] = + { + .name = _("Stench"), + .description = COMPOUND_STRING("May cause a foe to flinch."), + }, + + [ABILITY_DRIZZLE] = + { + .name = _("Drizzle"), + .description = COMPOUND_STRING("Summons rain in battle."), + }, + + [ABILITY_SPEED_BOOST] = + { + .name = _("Speed Boost"), + .description = COMPOUND_STRING("Gradually boosts Speed."), + }, + + [ABILITY_BATTLE_ARMOR] = + { + .name = _("Battle Armor"), + .description = COMPOUND_STRING("Blocks critical hits."), + }, + + [ABILITY_STURDY] = + { + .name = _("Sturdy"), + .description = COMPOUND_STRING("Negates 1-hit KO attacks."), + }, + + [ABILITY_DAMP] = + { + .name = _("Damp"), + .description = COMPOUND_STRING("Prevents self-destruction."), + }, + + [ABILITY_LIMBER] = + { + .name = _("Limber"), + .description = COMPOUND_STRING("Prevents paralysis."), + }, + + [ABILITY_SAND_VEIL] = + { + .name = _("Sand Veil"), + .description = COMPOUND_STRING("Ups evasion in a sandstorm."), + }, + + [ABILITY_STATIC] = + { + .name = _("Static"), + .description = COMPOUND_STRING("Paralyzes on contact."), + }, + + [ABILITY_VOLT_ABSORB] = + { + .name = _("Volt Absorb"), + .description = COMPOUND_STRING("Turns electricity into HP."), + }, + + [ABILITY_WATER_ABSORB] = + { + .name = _("Water Absorb"), + .description = COMPOUND_STRING("Changes water into HP."), + }, + + [ABILITY_OBLIVIOUS] = + { + .name = _("Oblivious"), + .description = COMPOUND_STRING("Prevents attraction."), + }, + + [ABILITY_CLOUD_NINE] = + { + .name = _("Cloud Nine"), + .description = COMPOUND_STRING("Negates weather effects."), + }, + + [ABILITY_COMPOUND_EYES] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Compound Eyes"), + #else + .name = _("CompoundEyes"), + #endif + .description = COMPOUND_STRING("Raises accuracy."), + }, + + [ABILITY_INSOMNIA] = + { + .name = _("Insomnia"), + .description = COMPOUND_STRING("Prevents sleep."), + }, + + [ABILITY_COLOR_CHANGE] = + { + .name = _("Color Change"), + .description = COMPOUND_STRING("Changes type to foe's move."), + }, + + [ABILITY_IMMUNITY] = + { + .name = _("Immunity"), + .description = COMPOUND_STRING("Prevents poisoning."), + }, + + [ABILITY_FLASH_FIRE] = + { + .name = _("Flash Fire"), + .description = COMPOUND_STRING("Powers up if hit by fire."), + }, + + [ABILITY_SHIELD_DUST] = + { + .name = _("Shield Dust"), + .description = COMPOUND_STRING("Prevents added effects."), + }, + + [ABILITY_OWN_TEMPO] = + { + .name = _("Own Tempo"), + .description = COMPOUND_STRING("Prevents confusion."), + }, + + [ABILITY_SUCTION_CUPS] = + { + .name = _("Suction Cups"), + .description = COMPOUND_STRING("Firmly anchors the body."), + }, + + [ABILITY_INTIMIDATE] = + { + .name = _("Intimidate"), + .description = COMPOUND_STRING("Lowers the foe's Attack."), + }, + + [ABILITY_SHADOW_TAG] = + { + .name = _("Shadow Tag"), + .description = COMPOUND_STRING("Prevents the foe's escape."), + }, + + [ABILITY_ROUGH_SKIN] = + { + .name = _("Rough Skin"), + .description = COMPOUND_STRING("Hurts to touch."), + }, + + [ABILITY_WONDER_GUARD] = + { + .name = _("Wonder Guard"), + .description = COMPOUND_STRING("“Supereffective” hits."), + }, + + [ABILITY_LEVITATE] = + { + .name = _("Levitate"), + .description = COMPOUND_STRING("Not hit by Ground attacks."), + }, + + [ABILITY_EFFECT_SPORE] = + { + .name = _("Effect Spore"), + .description = COMPOUND_STRING("Leaves spores on contact."), + }, + + [ABILITY_SYNCHRONIZE] = + { + .name = _("Synchronize"), + .description = COMPOUND_STRING("Passes on status problems."), + }, + + [ABILITY_CLEAR_BODY] = + { + .name = _("Clear Body"), + .description = COMPOUND_STRING("Prevents ability reduction."), + }, + + [ABILITY_NATURAL_CURE] = + { + .name = _("Natural Cure"), + .description = COMPOUND_STRING("Heals upon switching out."), + }, + + [ABILITY_LIGHTNING_ROD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Lightning Rod"), + #else + .name = _("LightningRod"), + #endif + .description = COMPOUND_STRING("Draws electrical moves."), + }, + + [ABILITY_SERENE_GRACE] = + { + .name = _("Serene Grace"), + .description = COMPOUND_STRING("Promotes added effects."), + }, + + [ABILITY_SWIFT_SWIM] = + { + .name = _("Swift Swim"), + .description = COMPOUND_STRING("Raises Speed in rain."), + }, + + [ABILITY_CHLOROPHYLL] = + { + .name = _("Chlorophyll"), + .description = COMPOUND_STRING("Raises Speed in sunshine."), + }, + + [ABILITY_ILLUMINATE] = + { + .name = _("Illuminate"), + .description = COMPOUND_STRING("Encounter rate increases."), + }, + + [ABILITY_TRACE] = + { + .name = _("Trace"), + .description = COMPOUND_STRING("Copies special ability."), + }, + + [ABILITY_HUGE_POWER] = + { + .name = _("Huge Power"), + .description = COMPOUND_STRING("Raises Attack."), + }, + + [ABILITY_POISON_POINT] = + { + .name = _("Poison Point"), + .description = COMPOUND_STRING("Poisons foe on contact."), + }, + + [ABILITY_INNER_FOCUS] = + { + .name = _("Inner Focus"), + .description = COMPOUND_STRING("Prevents flinching."), + }, + + [ABILITY_MAGMA_ARMOR] = + { + .name = _("Magma Armor"), + .description = COMPOUND_STRING("Prevents freezing."), + }, + + [ABILITY_WATER_VEIL] = + { + .name = _("Water Veil"), + .description = COMPOUND_STRING("Prevents burns."), + }, + + [ABILITY_MAGNET_PULL] = + { + .name = _("Magnet Pull"), + .description = COMPOUND_STRING("Traps Steel-type Pokémon."), + }, + + [ABILITY_SOUNDPROOF] = + { + .name = _("Soundproof"), + .description = COMPOUND_STRING("Avoids sound-based moves."), + }, + + [ABILITY_RAIN_DISH] = + { + .name = _("Rain Dish"), + .description = COMPOUND_STRING("Slight HP recovery in rain."), + }, + + [ABILITY_SAND_STREAM] = + { + .name = _("Sand Stream"), + .description = COMPOUND_STRING("Summons a sandstorm."), + }, + + [ABILITY_PRESSURE] = + { + .name = _("Pressure"), + .description = COMPOUND_STRING("Raises foe's PP usage."), + }, + + [ABILITY_THICK_FAT] = + { + .name = _("Thick Fat"), + .description = COMPOUND_STRING("Heat-and-cold protection."), + }, + + [ABILITY_EARLY_BIRD] = + { + .name = _("Early Bird"), + .description = COMPOUND_STRING("Awakens quickly from sleep."), + }, + + [ABILITY_FLAME_BODY] = + { + .name = _("Flame Body"), + .description = COMPOUND_STRING("Burns the foe on contact."), + }, + + [ABILITY_RUN_AWAY] = + { + .name = _("Run Away"), + .description = COMPOUND_STRING("Makes escaping easier."), + }, + + [ABILITY_KEEN_EYE] = + { + .name = _("Keen Eye"), + .description = COMPOUND_STRING("Prevents loss of accuracy."), + }, + + [ABILITY_HYPER_CUTTER] = + { + .name = _("Hyper Cutter"), + .description = COMPOUND_STRING("Prevents Attack reduction."), + }, + + [ABILITY_PICKUP] = + { + .name = _("Pickup"), + .description = COMPOUND_STRING("May pick up items."), + }, + + [ABILITY_TRUANT] = + { + .name = _("Truant"), + .description = COMPOUND_STRING("Moves only every two turns."), + }, + + [ABILITY_HUSTLE] = + { + .name = _("Hustle"), + .description = COMPOUND_STRING("Trades accuracy for power."), + }, + + [ABILITY_CUTE_CHARM] = + { + .name = _("Cute Charm"), + .description = COMPOUND_STRING("Infatuates on contact."), + }, + + [ABILITY_PLUS] = + { + .name = _("Plus"), + .description = COMPOUND_STRING("Powers up with Minus."), + }, + + [ABILITY_MINUS] = + { + .name = _("Minus"), + .description = COMPOUND_STRING("Powers up with Plus."), + }, + + [ABILITY_FORECAST] = + { + .name = _("Forecast"), + .description = COMPOUND_STRING("Changes with the weather."), + }, + + [ABILITY_STICKY_HOLD] = + { + .name = _("Sticky Hold"), + .description = COMPOUND_STRING("Prevents item theft."), + }, + + [ABILITY_SHED_SKIN] = + { + .name = _("Shed Skin"), + .description = COMPOUND_STRING("Heals the body by shedding."), + }, + + [ABILITY_GUTS] = + { + .name = _("Guts"), + .description = COMPOUND_STRING("Ups Attack if suffering."), + }, + + [ABILITY_MARVEL_SCALE] = + { + .name = _("Marvel Scale"), + .description = COMPOUND_STRING("Ups Defense if suffering."), + }, + + [ABILITY_LIQUID_OOZE] = + { + .name = _("Liquid Ooze"), + .description = COMPOUND_STRING("Draining causes injury."), + }, + + [ABILITY_OVERGROW] = + { + .name = _("Overgrow"), + .description = COMPOUND_STRING("Ups Grass moves in a pinch."), + }, + + [ABILITY_BLAZE] = + { + .name = _("Blaze"), + .description = COMPOUND_STRING("Ups Fire moves in a pinch."), + }, + + [ABILITY_TORRENT] = + { + .name = _("Torrent"), + .description = COMPOUND_STRING("Ups Water moves in a pinch."), + }, + + [ABILITY_SWARM] = + { + .name = _("Swarm"), + .description = COMPOUND_STRING("Ups Bug moves in a pinch."), + }, + + [ABILITY_ROCK_HEAD] = + { + .name = _("Rock Head"), + .description = COMPOUND_STRING("Prevents recoil damage."), + }, + + [ABILITY_DROUGHT] = + { + .name = _("Drought"), + .description = COMPOUND_STRING("Summons sunlight in battle."), + }, + + [ABILITY_ARENA_TRAP] = + { + .name = _("Arena Trap"), + .description = COMPOUND_STRING("Prevents fleeing."), + }, + + [ABILITY_VITAL_SPIRIT] = + { + .name = _("Vital Spirit"), + .description = COMPOUND_STRING("Prevents sleep."), + }, + + [ABILITY_WHITE_SMOKE] = + { + .name = _("White Smoke"), + .description = COMPOUND_STRING("Prevents ability reduction."), + }, + + [ABILITY_PURE_POWER] = + { + .name = _("Pure Power"), + .description = COMPOUND_STRING("Raises Attack."), + }, + + [ABILITY_SHELL_ARMOR] = + { + .name = _("Shell Armor"), + .description = COMPOUND_STRING("Blocks critical hits."), + }, + + [ABILITY_AIR_LOCK] = + { + .name = _("Air Lock"), + .description = COMPOUND_STRING("Negates weather effects."), + }, + + [ABILITY_TANGLED_FEET] = + { + .name = _("Tangled Feet"), + .description = COMPOUND_STRING("Ups evasion if confused."), + }, + + [ABILITY_MOTOR_DRIVE] = + { + .name = _("Motor Drive"), + .description = COMPOUND_STRING("Electricity raises Speed."), + }, + + [ABILITY_RIVALRY] = + { + .name = _("Rivalry"), + .description = COMPOUND_STRING("Powers up against rivals."), + }, + + [ABILITY_STEADFAST] = + { + .name = _("Steadfast"), + .description = COMPOUND_STRING("Flinching raises Speed."), + }, + + [ABILITY_SNOW_CLOAK] = + { + .name = _("Snow Cloak"), + .description = COMPOUND_STRING("Ups evasion in Hail or Snow."), + }, + + [ABILITY_GLUTTONY] = + { + .name = _("Gluttony"), + .description = COMPOUND_STRING("Eats Berries early."), + }, + + [ABILITY_ANGER_POINT] = + { + .name = _("Anger Point"), + .description = COMPOUND_STRING("Critical hits raise Attack."), + }, + + [ABILITY_UNBURDEN] = + { + .name = _("Unburden"), + .description = COMPOUND_STRING("Using a hold item ups Speed."), + }, + + [ABILITY_HEATPROOF] = + { + .name = _("Heatproof"), + .description = COMPOUND_STRING("Heat and burn protection."), + }, + + [ABILITY_SIMPLE] = + { + .name = _("Simple"), + .description = COMPOUND_STRING("Prone to wild stat changes."), + }, + + [ABILITY_DRY_SKIN] = + { + .name = _("Dry Skin"), + .description = COMPOUND_STRING("Prefers moisture to heat."), + }, + + [ABILITY_DOWNLOAD] = + { + .name = _("Download"), + .description = COMPOUND_STRING("Adjusts power favorably."), + }, + + [ABILITY_IRON_FIST] = + { + .name = _("Iron Fist"), + .description = COMPOUND_STRING("Boosts punching moves."), + }, + + [ABILITY_POISON_HEAL] = + { + .name = _("Poison Heal"), + .description = COMPOUND_STRING("Restores HP if poisoned."), + }, + + [ABILITY_ADAPTABILITY] = + { + .name = _("Adaptability"), + .description = COMPOUND_STRING("Boosts same type attacks."), + }, + + [ABILITY_SKILL_LINK] = + { + .name = _("Skill Link"), + .description = COMPOUND_STRING("Multi-hit moves hit 5 times."), + }, + + [ABILITY_HYDRATION] = + { + .name = _("Hydration"), + .description = COMPOUND_STRING("Cures status in rain."), + }, + + [ABILITY_SOLAR_POWER] = + { + .name = _("Solar Power"), + .description = COMPOUND_STRING("Powers up in sunshine."), + }, + + [ABILITY_QUICK_FEET] = + { + .name = _("Quick Feet"), + .description = COMPOUND_STRING("Ups Speed if suffering."), + }, + + [ABILITY_NORMALIZE] = + { + .name = _("Normalize"), + .description = COMPOUND_STRING("Moves become Normal-type."), + }, + + [ABILITY_SNIPER] = + { + .name = _("Sniper"), + .description = COMPOUND_STRING("Boosts critical hits."), + }, + + [ABILITY_MAGIC_GUARD] = + { + .name = _("Magic Guard"), + .description = COMPOUND_STRING("Only damaged by attacks."), + }, + + [ABILITY_NO_GUARD] = + { + .name = _("No Guard"), + .description = COMPOUND_STRING("Ensures that all moves hit."), + }, + + [ABILITY_STALL] = + { + .name = _("Stall"), + .description = COMPOUND_STRING("Always moves last."), + }, + + [ABILITY_TECHNICIAN] = + { + .name = _("Technician"), + .description = COMPOUND_STRING("Boosts weaker moves."), + }, + + [ABILITY_LEAF_GUARD] = + { + .name = _("Leaf Guard"), + .description = COMPOUND_STRING("Blocks status in sunshine."), + }, + + [ABILITY_KLUTZ] = + { + .name = _("Klutz"), + .description = COMPOUND_STRING("Can't use hold items."), + }, + + [ABILITY_MOLD_BREAKER] = + { + .name = _("Mold Breaker"), + .description = COMPOUND_STRING("Moves hit through abilities."), + }, + + [ABILITY_SUPER_LUCK] = + { + .name = _("Super Luck"), + .description = COMPOUND_STRING("Critical hits land often."), + }, + + [ABILITY_AFTERMATH] = + { + .name = _("Aftermath"), + .description = COMPOUND_STRING("Fainting damages the foe."), + }, + + [ABILITY_ANTICIPATION] = + { + .name = _("Anticipation"), + .description = COMPOUND_STRING("Senses dangerous moves."), + }, + + [ABILITY_FOREWARN] = + { + .name = _("Forewarn"), + .description = COMPOUND_STRING("Determines a foe's move."), + }, + + [ABILITY_UNAWARE] = + { + .name = _("Unaware"), + .description = COMPOUND_STRING("Ignores stat changes."), + }, + + [ABILITY_TINTED_LENS] = + { + .name = _("Tinted Lens"), + .description = COMPOUND_STRING("Ups “not very effective”."), + }, + + [ABILITY_FILTER] = + { + .name = _("Filter"), + .description = COMPOUND_STRING("Weakens “supereffective”."), + }, + + [ABILITY_SLOW_START] = + { + .name = _("Slow Start"), + .description = COMPOUND_STRING("Takes a while to get going."), + }, + + [ABILITY_SCRAPPY] = + { + .name = _("Scrappy"), + .description = COMPOUND_STRING("Hits Ghost-type Pokémon."), + }, + + [ABILITY_STORM_DRAIN] = + { + .name = _("Storm Drain"), + .description = COMPOUND_STRING("Draws in Water moves."), + }, + + [ABILITY_ICE_BODY] = + { + .name = _("Ice Body"), + .description = COMPOUND_STRING("HP recovery in Hail or Snow."), + }, + + [ABILITY_SOLID_ROCK] = + { + .name = _("Solid Rock"), + .description = COMPOUND_STRING("Weakens “supereffective”."), + }, + + [ABILITY_SNOW_WARNING] = + { + .name = _("Snow Warning"), + .description = COMPOUND_STRING("Summons a Hailstorm."), + }, + + [ABILITY_HONEY_GATHER] = + { + .name = _("Honey Gather"), + .description = COMPOUND_STRING("May gather Honey."), + }, + + [ABILITY_FRISK] = + { + .name = _("Frisk"), + .description = COMPOUND_STRING("Checks a foe's item."), + }, + + [ABILITY_RECKLESS] = + { + .name = _("Reckless"), + .description = COMPOUND_STRING("Boosts moves with recoil."), + }, + + [ABILITY_MULTITYPE] = + { + .name = _("Multitype"), + .description = COMPOUND_STRING("Changes type to its Plate."), + }, + + [ABILITY_FLOWER_GIFT] = + { + .name = _("Flower Gift"), + .description = COMPOUND_STRING("Allies power up in sunshine."), + }, + + [ABILITY_BAD_DREAMS] = + { + .name = _("Bad Dreams"), + .description = COMPOUND_STRING("Damages sleeping Pokémon."), + }, + + [ABILITY_PICKPOCKET] = + { + .name = _("Pickpocket"), + .description = COMPOUND_STRING("Steals the foe's held item."), + }, + + [ABILITY_SHEER_FORCE] = + { + .name = _("Sheer Force"), + .description = COMPOUND_STRING("Trades effects for power."), + }, + + [ABILITY_CONTRARY] = + { + .name = _("Contrary"), + .description = COMPOUND_STRING("Inverts stat changes."), + }, + + [ABILITY_UNNERVE] = + { + .name = _("Unnerve"), + .description = COMPOUND_STRING("Foes can't eat Berries."), + }, + + [ABILITY_DEFIANT] = + { + .name = _("Defiant"), + .description = COMPOUND_STRING("Lowered stats up Attack."), + }, + + [ABILITY_DEFEATIST] = + { + .name = _("Defeatist"), + .description = COMPOUND_STRING("Gives up at half HP."), + }, + + [ABILITY_CURSED_BODY] = + { + .name = _("Cursed Body"), + .description = COMPOUND_STRING("Disables moves on contact."), + }, + + [ABILITY_HEALER] = + { + .name = _("Healer"), + .description = COMPOUND_STRING("Heals partner Pokémon."), + }, + + [ABILITY_FRIEND_GUARD] = + { + .name = _("Friend Guard"), + .description = COMPOUND_STRING("Lowers damage to partner."), + }, + + [ABILITY_WEAK_ARMOR] = + { + .name = _("Weak Armor"), + .description = COMPOUND_STRING("Its stats change when hit."), + }, + + [ABILITY_HEAVY_METAL] = + { + .name = _("Heavy Metal"), + .description = COMPOUND_STRING("Doubles weight."), + }, + + [ABILITY_LIGHT_METAL] = + { + .name = _("Light Metal"), + .description = COMPOUND_STRING("Halves weight."), + }, + + [ABILITY_MULTISCALE] = + { + .name = _("Multiscale"), + .description = COMPOUND_STRING("Halves damage at full HP."), + }, + + [ABILITY_TOXIC_BOOST] = + { + .name = _("Toxic Boost"), + .description = COMPOUND_STRING("Ups Attack if poisoned."), + }, + + [ABILITY_FLARE_BOOST] = + { + .name = _("Flare Boost"), + .description = COMPOUND_STRING("Ups Sp. Atk if burned."), + }, + + [ABILITY_HARVEST] = + { + .name = _("Harvest"), + .description = COMPOUND_STRING("May recycle a used Berry."), + }, + + [ABILITY_TELEPATHY] = + { + .name = _("Telepathy"), + .description = COMPOUND_STRING("Can't be damaged by an ally."), + }, + + [ABILITY_MOODY] = + { + .name = _("Moody"), + .description = COMPOUND_STRING("Stats change gradually."), + }, + + [ABILITY_OVERCOAT] = + { + .name = _("Overcoat"), + .description = COMPOUND_STRING("Blocks weather and powder."), + }, + + [ABILITY_POISON_TOUCH] = + { + .name = _("Poison Touch"), + .description = COMPOUND_STRING("Poisons foe on contact."), + }, + + [ABILITY_REGENERATOR] = + { + .name = _("Regenerator"), + .description = COMPOUND_STRING("Heals upon switching out."), + }, + + [ABILITY_BIG_PECKS] = + { + .name = _("Big Pecks"), + .description = COMPOUND_STRING("Prevents Defense loss."), + }, + + [ABILITY_SAND_RUSH] = + { + .name = _("Sand Rush"), + .description = COMPOUND_STRING("Ups Speed in a sandstorm."), + }, + + [ABILITY_WONDER_SKIN] = + { + .name = _("Wonder Skin"), + .description = COMPOUND_STRING("May avoid status problems."), + }, + + [ABILITY_ANALYTIC] = + { + .name = _("Analytic"), + .description = COMPOUND_STRING("Moving last boosts power."), + }, + + [ABILITY_ILLUSION] = + { + .name = _("Illusion"), + .description = COMPOUND_STRING("Appears as a partner."), + }, + + [ABILITY_IMPOSTER] = + { + .name = _("Imposter"), + .description = COMPOUND_STRING("Transforms into the foe."), + }, + + [ABILITY_INFILTRATOR] = + { + .name = _("Infiltrator"), + .description = COMPOUND_STRING("Passes through barriers."), + }, + + [ABILITY_MUMMY] = + { + .name = _("Mummy"), + .description = COMPOUND_STRING("Spreads with contact."), + }, + + [ABILITY_MOXIE] = + { + .name = _("Moxie"), + .description = COMPOUND_STRING("KOs raise Attack."), + }, + + [ABILITY_JUSTIFIED] = + { + .name = _("Justified"), + .description = COMPOUND_STRING("Dark hits raise Attack."), + }, + + [ABILITY_RATTLED] = + { + .name = _("Rattled"), + .description = COMPOUND_STRING("Raises Speed when scared."), + }, + + [ABILITY_MAGIC_BOUNCE] = + { + .name = _("Magic Bounce"), + .description = COMPOUND_STRING("Reflects status moves."), + }, + + [ABILITY_SAP_SIPPER] = + { + .name = _("Sap Sipper"), + .description = COMPOUND_STRING("Grass increases Attack."), + }, + + [ABILITY_PRANKSTER] = + { + .name = _("Prankster"), + .description = COMPOUND_STRING("Status moves go first."), + }, + + [ABILITY_SAND_FORCE] = + { + .name = _("Sand Force"), + .description = COMPOUND_STRING("Powers up in a sandstorm."), + }, + + [ABILITY_IRON_BARBS] = + { + .name = _("Iron Barbs"), + .description = COMPOUND_STRING("Hurts to touch."), + }, + + [ABILITY_ZEN_MODE] = + { + .name = _("Zen Mode"), + .description = COMPOUND_STRING("Transforms at half HP."), + }, + + [ABILITY_VICTORY_STAR] = + { + .name = _("Victory Star"), + .description = COMPOUND_STRING("Raises party accuracy."), + }, + + [ABILITY_TURBOBLAZE] = + { + .name = _("Turboblaze"), + .description = COMPOUND_STRING("Moves hit through abilities."), + }, + + [ABILITY_TERAVOLT] = + { + .name = _("Teravolt"), + .description = COMPOUND_STRING("Moves hit through abilities."), + }, + + [ABILITY_AROMA_VEIL] = + { + .name = _("Aroma Veil"), + .description = COMPOUND_STRING("Prevents limiting of moves."), + }, + + [ABILITY_FLOWER_VEIL] = + { + .name = _("Flower Veil"), + .description = COMPOUND_STRING("Protects Grass-types."), + }, + + [ABILITY_CHEEK_POUCH] = + { + .name = _("Cheek Pouch"), + .description = COMPOUND_STRING("Eating Berries restores HP."), + }, + + [ABILITY_PROTEAN] = + { + .name = _("Protean"), + .description = COMPOUND_STRING("Changes type to used move."), + }, + + [ABILITY_FUR_COAT] = + { + .name = _("Fur Coat"), + .description = COMPOUND_STRING("Raises Defense."), + }, + + [ABILITY_MAGICIAN] = + { + .name = _("Magician"), + .description = COMPOUND_STRING("Steals the foe's held item."), + }, + + [ABILITY_BULLETPROOF] = + { + .name = _("Bulletproof"), + .description = COMPOUND_STRING("Avoids some projectiles."), + }, + + [ABILITY_COMPETITIVE] = + { + .name = _("Competitive"), + .description = COMPOUND_STRING("Lowered stats up Sp. Atk."), + }, + + [ABILITY_STRONG_JAW] = + { + .name = _("Strong Jaw"), + .description = COMPOUND_STRING("Boosts biting moves."), + }, + + [ABILITY_REFRIGERATE] = + { + .name = _("Refrigerate"), + .description = COMPOUND_STRING("Normal moves become Ice."), + }, + + [ABILITY_SWEET_VEIL] = + { + .name = _("Sweet Veil"), + .description = COMPOUND_STRING("Prevents party from sleep."), + }, + + [ABILITY_STANCE_CHANGE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Stance Change"), + #else + .name = _("StanceChange"), + #endif + .description = COMPOUND_STRING("Transforms as it battles."), + }, + + [ABILITY_GALE_WINGS] = + { + .name = _("Gale Wings"), + .description = COMPOUND_STRING("Flying moves go first."), + }, + + [ABILITY_MEGA_LAUNCHER] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Mega Launcher"), + #else + .name = _("MegaLauncher"), + #endif + .description = COMPOUND_STRING("Boosts pulse moves."), + }, + + [ABILITY_GRASS_PELT] = + { + .name = _("Grass Pelt"), + .description = COMPOUND_STRING("Ups Defense in grass."), + }, + + [ABILITY_SYMBIOSIS] = + { + .name = _("Symbiosis"), + .description = COMPOUND_STRING("Passes its item to an ally."), + }, + + [ABILITY_TOUGH_CLAWS] = + { + .name = _("Tough Claws"), + .description = COMPOUND_STRING("Boosts contact moves."), + }, + + [ABILITY_PIXILATE] = + { + .name = _("Pixilate"), + .description = COMPOUND_STRING("Normal moves become Fairy."), + }, + + [ABILITY_GOOEY] = + { + .name = _("Gooey"), + .description = COMPOUND_STRING("Lowers Speed on contact."), + }, + + [ABILITY_AERILATE] = + { + .name = _("Aerilate"), + .description = COMPOUND_STRING("Normal moves become Flying."), + }, + + [ABILITY_PARENTAL_BOND] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Parental Bond"), + #else + .name = _("ParentalBond"), + #endif + .description = COMPOUND_STRING("Moves hit twice."), + }, + + [ABILITY_DARK_AURA] = + { + .name = _("Dark Aura"), + .description = COMPOUND_STRING("Boosts Dark moves."), + }, + + [ABILITY_FAIRY_AURA] = + { + .name = _("Fairy Aura"), + .description = COMPOUND_STRING("Boosts Fairy moves."), + }, + + [ABILITY_AURA_BREAK] = + { + .name = _("Aura Break"), + .description = COMPOUND_STRING("Reverse aura abilities."), + }, + + [ABILITY_PRIMORDIAL_SEA] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Primordial Sea"), + #else + .name = _("PrimrdialSea"), + #endif + .description = COMPOUND_STRING("Summons heavy rain."), + }, + + [ABILITY_DESOLATE_LAND] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Desolate Land"), + #else + .name = _("DesolateLand"), + #endif + .description = COMPOUND_STRING("Summons intense sunlight."), + }, + + [ABILITY_DELTA_STREAM] = + { + .name = _("Delta Stream"), + .description = COMPOUND_STRING("Summons strong winds."), + }, + + [ABILITY_STAMINA] = + { + .name = _("Stamina"), + .description = COMPOUND_STRING("Boosts Defense when hit."), + }, + + [ABILITY_WIMP_OUT] = + { + .name = _("Wimp Out"), + .description = COMPOUND_STRING("Flees at half HP."), + }, + + [ABILITY_EMERGENCY_EXIT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Emergency Exit"), + #else + .name = _("EmergncyExit"), + #endif + .description = COMPOUND_STRING("Flees at half HP."), + }, + + [ABILITY_WATER_COMPACTION] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Water Compaction"), + #else + .name = _("WtrCmpaction"), + #endif + .description = COMPOUND_STRING("Water boosts Defense."), + }, + + [ABILITY_MERCILESS] = + { + .name = _("Merciless"), + .description = COMPOUND_STRING("Criticals poisoned foes."), + }, + + [ABILITY_SHIELDS_DOWN] = + { + .name = _("Shields Down"), + .description = COMPOUND_STRING("Shell breaks at half HP."), + }, + + [ABILITY_STAKEOUT] = + { + .name = _("Stakeout"), + .description = COMPOUND_STRING("Stronger as foes switch in."), + }, + + [ABILITY_WATER_BUBBLE] = + { + .name = _("Water Bubble"), + .description = COMPOUND_STRING("Guards from fire and burns."), + }, + + [ABILITY_STEELWORKER] = + { + .name = _("Steelworker"), + .description = COMPOUND_STRING("Powers up Steel moves."), + }, + + [ABILITY_BERSERK] = + { + .name = _("Berserk"), + .description = COMPOUND_STRING("Boosts Sp. Atk at low HP."), + }, + + [ABILITY_SLUSH_RUSH] = + { + .name = _("Slush Rush"), + .description = COMPOUND_STRING("Raises Speed in Hail or Snow."), + }, + + [ABILITY_LONG_REACH] = + { + .name = _("Long Reach"), + .description = COMPOUND_STRING("Never makes contact."), + }, + + [ABILITY_LIQUID_VOICE] = + { + .name = _("Liquid Voice"), + .description = COMPOUND_STRING("Makes sound moves Water."), + }, + + [ABILITY_TRIAGE] = + { + .name = _("Triage"), + .description = COMPOUND_STRING("Healing moves go first."), + }, + + [ABILITY_GALVANIZE] = + { + .name = _("Galvanize"), + .description = COMPOUND_STRING("Normal moves turn Electric."), + }, + + [ABILITY_SURGE_SURFER] = + { + .name = _("Surge Surfer"), + .description = COMPOUND_STRING("Faster on electricity."), + }, + + [ABILITY_SCHOOLING] = + { + .name = _("Schooling"), + .description = COMPOUND_STRING("Forms a school when strong."), + }, + + [ABILITY_DISGUISE] = + { + .name = _("Disguise"), + .description = COMPOUND_STRING("Decoy protects it once."), + }, + + [ABILITY_BATTLE_BOND] = + { + .name = _("Battle Bond"), + .description = COMPOUND_STRING("Changes form after a KO."), + }, + + [ABILITY_POWER_CONSTRUCT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Power Construct"), + #else + .name = _("PwrConstruct"), + #endif + .description = COMPOUND_STRING("Cells aid it when weakened."), + }, + + [ABILITY_CORROSION] = + { + .name = _("Corrosion"), + .description = COMPOUND_STRING("Poisons any type."), + }, + + [ABILITY_COMATOSE] = + { + .name = _("Comatose"), + .description = COMPOUND_STRING("Always drowsing."), + }, + + [ABILITY_QUEENLY_MAJESTY] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Queenly Majesty"), + #else + .name = _("QueenlyMjsty"), + #endif + .description = COMPOUND_STRING("Protects from priority."), + }, + + [ABILITY_INNARDS_OUT] = + { + .name = _("Innards Out"), + .description = COMPOUND_STRING("Hurts foe when defeated."), + }, + + [ABILITY_DANCER] = + { + .name = _("Dancer"), + .description = COMPOUND_STRING("Dances along with others."), + }, + + [ABILITY_BATTERY] = + { + .name = _("Battery"), + .description = COMPOUND_STRING("Boosts ally's Sp. Atk."), + }, + + [ABILITY_FLUFFY] = + { + .name = _("Fluffy"), + .description = COMPOUND_STRING("Tougher but flammable."), + }, + + [ABILITY_DAZZLING] = + { + .name = _("Dazzling"), + .description = COMPOUND_STRING("Protects from priority."), + }, + + [ABILITY_SOUL_HEART] = + { + .name = _("Soul-Heart"), + .description = COMPOUND_STRING("KOs raise Sp. Atk."), + }, + + [ABILITY_TANGLING_HAIR] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Tangling Hair"), + #else + .name = _("TanglingHair"), + #endif + .description = COMPOUND_STRING("Lowers Speed on contact."), + }, + + [ABILITY_RECEIVER] = + { + .name = _("Receiver"), + .description = COMPOUND_STRING("Copies ally's ability."), + }, + + [ABILITY_POWER_OF_ALCHEMY] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Power Of Alchemy"), + #else + .name = _("PwrOfAlchemy"), + #endif + .description = COMPOUND_STRING("Copies ally's ability."), + }, + + [ABILITY_BEAST_BOOST] = + { + .name = _("Beast Boost"), + .description = COMPOUND_STRING("KOs boost best stat."), + }, + + [ABILITY_RKS_SYSTEM] = + { + .name = _("RKS System"), + .description = COMPOUND_STRING("Memories change its type."), + }, + + [ABILITY_ELECTRIC_SURGE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Electric Surge"), + #else + .name = _("ElectrcSurge"), + #endif + .description = COMPOUND_STRING("Field becomes Electric."), + }, + + [ABILITY_PSYCHIC_SURGE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Psychic Surge"), + #else + .name = _("PsychicSurge"), + #endif + .description = COMPOUND_STRING("Field becomes weird."), + }, + + [ABILITY_MISTY_SURGE] = + { + .name = _("Misty Surge"), + .description = COMPOUND_STRING("Field becomes misty."), + }, + + [ABILITY_GRASSY_SURGE] = + { + .name = _("Grassy Surge"), + .description = COMPOUND_STRING("Field becomes grassy."), + }, + + [ABILITY_FULL_METAL_BODY] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Full Metal Body"), + #else + .name = _("FullMetalBdy"), + #endif + .description = COMPOUND_STRING("Prevents stat reduction."), + }, + + [ABILITY_SHADOW_SHIELD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Shadow Shield"), + #else + .name = _("ShadowShield"), + #endif + .description = COMPOUND_STRING("Halves damage at full HP."), + }, + + [ABILITY_PRISM_ARMOR] = + { + .name = _("Prism Armor"), + .description = COMPOUND_STRING("Weakens “supereffective”."), + }, + + [ABILITY_NEUROFORCE] = + { + .name = _("Neuroforce"), + .description = COMPOUND_STRING("Ups “supereffective”."), + }, + + [ABILITY_INTREPID_SWORD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Intrepid Sword"), + #else + .name = _("IntrepidSwrd"), + #endif + .description = COMPOUND_STRING("Ups Attack on entry."), + }, + + [ABILITY_DAUNTLESS_SHIELD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Dauntless Shield"), + #else + .name = _("DauntlssShld"), + #endif + .description = COMPOUND_STRING("Ups Defense on entry."), + }, + + [ABILITY_LIBERO] = + { + .name = _("Libero"), + .description = COMPOUND_STRING("Changes type to move's."), + }, + + [ABILITY_BALL_FETCH] = + { + .name = _("Ball Fetch"), + .description = COMPOUND_STRING("Fetches failed Poké Ball."), + }, + + [ABILITY_COTTON_DOWN] = + { + .name = _("Cotton Down"), + .description = COMPOUND_STRING("Lower Speed of all when hit."), + }, + + [ABILITY_PROPELLER_TAIL] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Propeller Tail"), + #else + .name = _("PropellrTail"), + #endif + .description = COMPOUND_STRING("Ignores foe's redirection."), + }, + + [ABILITY_MIRROR_ARMOR] = + { + .name = _("Mirror Armor"), + .description = COMPOUND_STRING("Reflect stat decreases."), + }, + + [ABILITY_GULP_MISSILE] = + { + .name = _("Gulp Missile"), + .description = COMPOUND_STRING("If hit, spits prey from sea."), + }, + + [ABILITY_STALWART] = + { + .name = _("Stalwart"), + .description = COMPOUND_STRING("Ignores foe's redirection."), + }, + + [ABILITY_STEAM_ENGINE] = + { + .name = _("Steam Engine"), + .description = COMPOUND_STRING("Fire or Water hits up Speed."), + }, + + [ABILITY_PUNK_ROCK] = + { + .name = _("Punk Rock"), + .description = COMPOUND_STRING("Ups and resists sound."), + }, + + [ABILITY_SAND_SPIT] = + { + .name = _("Sand Spit"), + .description = COMPOUND_STRING("Creates a sandstorm if hit."), + }, + + [ABILITY_ICE_SCALES] = + { + .name = _("Ice Scales"), + .description = COMPOUND_STRING("Halves special damage."), + }, + + [ABILITY_RIPEN] = + { + .name = _("Ripen"), + .description = COMPOUND_STRING("Doubles effect of Berries."), + }, + + [ABILITY_ICE_FACE] = + { + .name = _("Ice Face"), + .description = COMPOUND_STRING("Hail or Snow renew free hit."), + }, + + [ABILITY_POWER_SPOT] = + { + .name = _("Power Spot"), + .description = COMPOUND_STRING("Powers up ally moves."), + }, + + [ABILITY_MIMICRY] = + { + .name = _("Mimicry"), + .description = COMPOUND_STRING("Changes type on terrain."), + }, + + [ABILITY_SCREEN_CLEANER] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Screen Cleaner"), + #else + .name = _("ScreenCleanr"), + #endif + .description = COMPOUND_STRING("Removes walls of light."), + }, + + [ABILITY_STEELY_SPIRIT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Steely Spirit"), + #else + .name = _("SteelySpirit"), + #endif + .description = COMPOUND_STRING("Boosts ally's Steel moves."), + }, + + [ABILITY_PERISH_BODY] = + { + .name = _("Perish Body"), + .description = COMPOUND_STRING("Foe faints in 3 turns if hit."), + }, + + [ABILITY_WANDERING_SPIRIT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Wandering Spirit"), + #else + .name = _("WandrngSprit"), + #endif + .description = COMPOUND_STRING("Trade abilities on contact."), + }, + + [ABILITY_GORILLA_TACTICS] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Gorilla Tactics"), + #else + .name = _("GorillaTacti"), + #endif + .description = COMPOUND_STRING("Ups Attack and locks move."), + }, + + [ABILITY_NEUTRALIZING_GAS] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Neutralizing Gas"), + #else + .name = _("NeutrlzngGas"), + #endif + .description = COMPOUND_STRING("All Abilities are nullified."), + }, + + [ABILITY_PASTEL_VEIL] = + { + .name = _("Pastel Veil"), + .description = COMPOUND_STRING("Protects team from poison."), + }, + + [ABILITY_HUNGER_SWITCH] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Hunger Switch"), + #else + .name = _("HungerSwitch"), + #endif + .description = COMPOUND_STRING("Changes form each turn."), + }, + + [ABILITY_QUICK_DRAW] = + { + .name = _("Quick Draw"), + .description = COMPOUND_STRING("Moves first occasionally."), + }, + + [ABILITY_UNSEEN_FIST] = + { + .name = _("Unseen Fist"), + .description = COMPOUND_STRING("Contact evades protection."), + }, + + [ABILITY_CURIOUS_MEDICINE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Curious Medicine"), + #else + .name = _("CuriusMedicn"), + #endif + .description = COMPOUND_STRING("Remove ally's stat changes."), + }, + + [ABILITY_TRANSISTOR] = + { + .name = _("Transistor"), + .description = COMPOUND_STRING("Ups Electric-type moves."), + }, + + [ABILITY_DRAGONS_MAW] = + { + .name = _("Dragon's Maw"), + .description = COMPOUND_STRING("Ups Dragon-type moves."), + }, + + [ABILITY_CHILLING_NEIGH] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Chilling Neigh"), + #else + .name = _("ChillngNeigh"), + #endif + .description = COMPOUND_STRING("KOs boost Attack stat."), + }, + + [ABILITY_GRIM_NEIGH] = + { + .name = _("Grim Neigh"), + .description = COMPOUND_STRING("KOs boost Sp. Atk stat."), + }, + + [ABILITY_AS_ONE_ICE_RIDER] = + { + .name = _("As One"), + .description = COMPOUND_STRING("Unnerve and Chilling Neigh."), + }, + + [ABILITY_AS_ONE_SHADOW_RIDER] = + { + .name = _("As One"), + .description = COMPOUND_STRING("Unnerve and Grim Neigh."), + }, + + [ABILITY_LINGERING_AROMA] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Lingering Aroma"), + #else + .name = _("LngerngAroma"), + #endif + .description = COMPOUND_STRING("Spreads with contact."), + }, + + [ABILITY_SEED_SOWER] = + { + .name = _("Seed Sower"), + .description = COMPOUND_STRING("Affects terrain when hit."), + }, + + [ABILITY_THERMAL_EXCHANGE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Thermal Exchange"), + #else + .name = _("ThrmlExchnge"), + #endif + .description = COMPOUND_STRING("Fire hits up Attack."), + }, + + [ABILITY_ANGER_SHELL] = + { + .name = _("Anger Shell"), + .description = COMPOUND_STRING("Gets angry at half HP."), + }, + + [ABILITY_PURIFYING_SALT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Purifying Salt"), + #else + .name = _("PurfyingSalt"), + #endif + .description = COMPOUND_STRING("Protected by pure salts."), + }, + + [ABILITY_WELL_BAKED_BODY] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Well-Baked Body"), + #else + .name = _("WellBakedBdy"), + #endif + .description = COMPOUND_STRING("Strengthened by Fire."), + }, + + [ABILITY_WIND_RIDER] = + { + .name = _("Wind Rider"), + .description = COMPOUND_STRING("Ups Attack if hit by wind."), + }, + + [ABILITY_GUARD_DOG] = + { + .name = _("Guard Dog"), + .description = COMPOUND_STRING("Cannot be intimidated."), + }, + + [ABILITY_ROCKY_PAYLOAD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Rocky Payload"), + #else + .name = _("RockyPayload"), + #endif + .description = COMPOUND_STRING("Powers up Rock moves."), + }, + + [ABILITY_WIND_POWER] = + { + .name = _("Wind Power"), + .description = COMPOUND_STRING("Gets charged by wind."), + }, + + [ABILITY_ZERO_TO_HERO] = + { + .name = _("Zero to Hero"), + .description = COMPOUND_STRING("Changes form on switch out."), + }, + + [ABILITY_COMMANDER] = + { + .name = _("Commander"), + .description = COMPOUND_STRING("Commands from Dondozo."), + }, + + [ABILITY_ELECTROMORPHOSIS] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Electromorphosis"), + #else + .name = _("Elecmrphosis"), + #endif + .description = COMPOUND_STRING("Gets Charged on contact."), + }, + + [ABILITY_PROTOSYNTHESIS] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Protosynthesis"), + #else + .name = _("Protosnthsis"), + #endif + .description = COMPOUND_STRING("Sun boosts best stat."), + }, + + [ABILITY_QUARK_DRIVE] = + { + .name = _("Quark Drive"), + .description = COMPOUND_STRING("Elec. field ups best stat."), + }, + + [ABILITY_GOOD_AS_GOLD] = + { + .name = _("Good as Gold"), + .description = COMPOUND_STRING("Avoids status problems."), + }, + + [ABILITY_VESSEL_OF_RUIN] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Vessel of Ruin"), + #else + .name = _("VesselOfRuin"), + #endif + .description = COMPOUND_STRING("Lowers foes' sp. damage."), + }, + + [ABILITY_SWORD_OF_RUIN] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Sword of Ruin"), + #else + .name = _("SwordOfRuin"), + #endif + .description = COMPOUND_STRING("Lowers foes' defense."), + }, + + [ABILITY_TABLETS_OF_RUIN] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Tablets of Ruin"), + #else + .name = _("TabltsOfRuin"), + #endif + .description = COMPOUND_STRING("Lowers foes' damage."), + }, + + [ABILITY_BEADS_OF_RUIN] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Beads of Ruin"), + #else + .name = _("BeadsOfRuin"), + #endif + .description = COMPOUND_STRING("Lowers foes' sp. defense."), + }, + + [ABILITY_ORICHALCUM_PULSE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Orichalcum Pulse"), + #else + .name = _("OrchlcumPlse"), + #endif + .description = COMPOUND_STRING("Summons sunlight in battle."), + }, + + [ABILITY_HADRON_ENGINE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Hadron Engine"), + #else + .name = _("HadronEngine"), + #endif + .description = COMPOUND_STRING("Field becomes Electric."), + }, + + [ABILITY_OPPORTUNIST] = + { + .name = _("Opportunist"), + .description = COMPOUND_STRING("Copies foe's stat change."), + }, + + [ABILITY_CUD_CHEW] = + { + .name = _("Cud Chew"), + .description = COMPOUND_STRING("Eats a used berry again."), + }, + + [ABILITY_SHARPNESS] = + { + .name = _("Sharpness"), + .description = COMPOUND_STRING("Strengthens slicing moves."), + }, + + [ABILITY_SUPREME_OVERLORD] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Supreme Overlord"), + #else + .name = _("SuprmeOvrlrd"), + #endif + .description = COMPOUND_STRING("Inherits fallen's strength."), + }, + + [ABILITY_COSTAR] = + { + .name = _("Costar"), + .description = COMPOUND_STRING("Copies ally's stat changes."), + }, + + [ABILITY_TOXIC_DEBRIS] = + { + .name = _("Toxic Debris"), + .description = COMPOUND_STRING("Throws poison spikes if hit."), + }, + + [ABILITY_ARMOR_TAIL] = + { + .name = _("Armor Tail"), + .description = COMPOUND_STRING("Protects from priority."), + }, + + [ABILITY_EARTH_EATER] = + { + .name = _("Earth Eater"), + .description = COMPOUND_STRING("Eats ground to heal HP."), + }, + + [ABILITY_MYCELIUM_MIGHT] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Mycelium Might"), + #else + .name = _("MceliumMight"), + #endif + .description = COMPOUND_STRING("Status moves never fail."), + }, + + [ABILITY_HOSPITALITY] = + { + .name = _("Hospitality"), + .description = COMPOUND_STRING("Restores ally's HP."), + }, + + [ABILITY_MINDS_EYE] = + { + .name = _("Mind's Eye"), + .description = COMPOUND_STRING("Keen Eye and Scrappy."), + }, + + [ABILITY_EMBODY_ASPECT_TEAL] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Embody Aspect"), + #else + .name = _("EmbodyAspect"), + #endif + .description = COMPOUND_STRING("Raises Speed."), + }, + + [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Embody Aspect"), + #else + .name = _("EmbodyAspect"), + #endif + .description = COMPOUND_STRING("Raises Attack."), + }, + + [ABILITY_EMBODY_ASPECT_WELLSPRING] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Embody Aspect"), + #else + .name = _("EmbodyAspect"), + #endif + .description = COMPOUND_STRING("Raises Sp. Def."), + }, + + [ABILITY_EMBODY_ASPECT_CORNERSTONE] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Embody Aspect"), + #else + .name = _("EmbodyAspect"), + #endif + .description = COMPOUND_STRING("Raises Defense."), + }, + + [ABILITY_TOXIC_CHAIN] = + { + .name = _("Toxic Chain"), + .description = COMPOUND_STRING("Moves can poison."), + }, + + [ABILITY_SUPERSWEET_SYRUP] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Supersweet Syrup"), + #else + .name = _("SuprswtSyrup"), + #endif + .description = COMPOUND_STRING("Lowers the foe's Speed."), + }, + + [ABILITY_TERA_SHIFT] = + { + .name = _("Tera Shift"), + .description = COMPOUND_STRING("Terasteralizes upon entry."), + }, + + [ABILITY_TERA_SHELL] = + { + .name = _("Tera Shell"), + .description = COMPOUND_STRING("Resistant to types at full HP."), + }, + + [ABILITY_TERAFORM_ZERO] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Teraform Zero"), + #else + .name = _("TeraformZero"), + #endif + .description = COMPOUND_STRING("Removes weather and terrain."), + }, + + [ABILITY_POISON_PUPPETEER] = + { + #if B_EXPANDED_ABILITY_NAMES == TRUE + .name = _("Poison Puppeteer"), + #else + .name = _("PoisnPuppter"), + #endif + .description = COMPOUND_STRING("Confuses poisoned foes."), + }, +}; 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 8284bbe664cd..ea4876f67fa3 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -13,6 +13,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .category = BATTLE_CATEGORY_PHYSICAL, .metronomeBanned = TRUE, .mirrorMoveBanned = TRUE, + .sketchBanned = TRUE, }, [MOVE_POUND] = @@ -2844,6 +2845,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = TRUE, }, [MOVE_SKETCH] = @@ -2868,6 +2870,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = TRUE, }, [MOVE_TRIPLE_KICK] = @@ -3063,6 +3066,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = BATTLE_CATEGORY_SPECIAL, + .windMove = TRUE, }, [MOVE_COTTON_SPORE] = @@ -5117,7 +5121,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_LUSTER_PURGE] = { .effect = EFFECT_SPECIAL_DEFENSE_DOWN_HIT, - .power = 70, + .power = (B_UPDATED_MOVE_DATA >= GEN_9) ? 95 : 70, .type = TYPE_PSYCHIC, .accuracy = 100, .pp = 5, @@ -5131,7 +5135,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_MIST_BALL] = { .effect = EFFECT_SPECIAL_ATTACK_DOWN_HIT, - .power = 70, + .power = (B_UPDATED_MOVE_DATA >= GEN_9) ? 95 : 70, .type = TYPE_PSYCHIC, .accuracy = 100, .pp = 5, @@ -7900,6 +7904,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .category = BATTLE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_RESET_STATS }, .magicCoatAffected = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_SEED_FLARE] = @@ -10463,6 +10468,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .ignoresProtect = TRUE, .ignoresSubstitute = TRUE, .metronomeBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_SHORE_UP] = @@ -11304,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, @@ -13220,6 +13226,8 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .ignoresProtect = TRUE, .mirrorMoveBanned = TRUE, .metronomeBanned = TRUE, + .healBlockBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_SALT_CURE] = @@ -13285,7 +13293,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_FILLET_AWAY] = { - .effect = EFFECT_PLACEHOLDER, // EFFECT_FILLET_AWAY + .effect = EFFECT_FILLET_AWAY, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, @@ -13620,7 +13628,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .category = BATTLE_CATEGORY_PHYSICAL, .makesContact = TRUE, .slicingMove = TRUE, - .healBlockBanned = B_EXTRAPOLATED_MOVE_FLAGS, + .healBlockBanned = TRUE, }, [MOVE_DOUBLE_SHOCK] = @@ -13704,6 +13712,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_WICKED_TORQUE] = @@ -13727,6 +13736,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_NOXIOUS_TORQUE] = @@ -13750,6 +13760,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_COMBAT_TORQUE] = @@ -13773,6 +13784,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_MAGICAL_TORQUE] = @@ -13796,6 +13808,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .instructBanned = TRUE, .encoreBanned = TRUE, .assistBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), }, [MOVE_PSYBLADE] = @@ -13854,7 +13867,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .category = BATTLE_CATEGORY_SPECIAL, .thawsUser = TRUE, .metronomeBanned = TRUE, - .healBlockBanned = B_EXTRAPOLATED_MOVE_FLAGS, + .healBlockBanned = TRUE, }, [MOVE_SYRUP_BOMB] = @@ -13874,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, @@ -13884,10 +13897,230 @@ 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_METEOR_BEAM, + .power = 130, + .type = TYPE_ELECTRIC, + .accuracy = 100, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + //.sheerForceBoost = TRUE, (uncomment when effect is implemented, otherwise it breaks the Sheer Force Test) + }, + + [MOVE_TERA_STARSTORM] = + { + .effect = EFFECT_PLACEHOLDER, //EFFECT_TERA_STARSTORM + .power = 120, + .type = TYPE_NORMAL, // Stellar type if used by Terapagos-Stellar + .accuracy = 100, + .pp = 5, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, // MOVE_TARGET_BOTH if used by Terapagos-Stellar + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + .assistBanned = TRUE, + .copycatBanned = TRUE, + .mimicBanned = TRUE, + .sketchBanned = (B_SKETCH_BANS >= GEN_9), + }, + + [MOVE_FICKLE_BEAM] = + { + .effect = EFFECT_FICKLE_BEAM, + .power = 80, + .type = TYPE_DRAGON, + .accuracy = 100, + .pp = 5, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + }, + + [MOVE_BURNING_BULWARK] = + { + .effect = EFFECT_PROTECT, + .power = 0, + .type = TYPE_FIRE, + .accuracy = 0, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_USER, + .priority = 4, + .category = BATTLE_CATEGORY_STATUS, + .zMove = { .effect = Z_EFFECT_RESET_STATS }, + .protectionMove = TRUE, + .ignoresProtect = TRUE, + .mirrorMoveBanned = TRUE, + .metronomeBanned = TRUE, + .copycatBanned = TRUE, + .assistBanned = TRUE, + }, + + [MOVE_THUNDERCLAP] = + { + .effect = EFFECT_SUCKER_PUNCH, + .power = 70, + .type = TYPE_ELECTRIC, + .accuracy = 100, + .pp = 5, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 1, + .category = BATTLE_CATEGORY_SPECIAL, + }, + + [MOVE_MIGHTY_CLEAVE] = + { + .effect = EFFECT_FEINT, + .power = 95, + .type = TYPE_ROCK, + .accuracy = 100, + .pp = 5, + .secondaryEffectChance = 100, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + .slicingMove = TRUE, + }, + + [MOVE_TACHYON_CUTTER] = + { + .effect = EFFECT_HIT, + .power = 50, + .type = TYPE_STEEL, + .accuracy = 0, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + .strikeCount = 2, + .slicingMove = TRUE, + }, + + [MOVE_HARD_PRESS] = + { + .effect = EFFECT_WRING_OUT, + .power = 1, + .type = TYPE_STEEL, + .accuracy = 100, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + }, + + [MOVE_DRAGON_CHEER] = + { + .effect = EFFECT_PLACEHOLDER, //EFFECT_DRAGON_CHEER + .power = 0, + .type = TYPE_DRAGON, + .accuracy = 0, + .pp = 15, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_ALLY, + .priority = 0, + .category = BATTLE_CATEGORY_STATUS, + .ignoresSubstitute = TRUE, + }, + + [MOVE_ALLURING_VOICE] = + { + .effect = EFFECT_CONFUSE_HIT, + .power = 80, + .type = TYPE_FAIRY, + .accuracy = 100, + .pp = 10, + .secondaryEffectChance = 100, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + .soundMove = TRUE, + .sheerForceBoost = TRUE, + .ignoresSubstitute = TRUE, + }, + + [MOVE_TEMPER_FLARE] = + { + .effect = EFFECT_STOMPING_TANTRUM, + .power = 75, + .type = TYPE_FIRE, + .accuracy = 100, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + }, + + [MOVE_SUPERCELL_SLAM] = + { + .effect = EFFECT_RECOIL_IF_MISS, + .power = 100, + .type = TYPE_ELECTRIC, + .accuracy = 95, + .pp = 15, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + }, + + [MOVE_PSYCHIC_NOISE] = + { + .effect = EFFECT_PLACEHOLDER, //EFFECT_PSYCHIC_NOISE + .power = 75, + .type = TYPE_PSYCHIC, + .accuracy = 100, + .pp = 10, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + .soundMove = TRUE, + .ignoresSubstitute = TRUE, + }, + + [MOVE_UPPER_HAND] = + { + .effect = EFFECT_PLACEHOLDER, //EFFECT_UPPER_HAND + .power = 65, + .type = TYPE_FIGHTING, + .accuracy = 100, + .pp = 15, + .secondaryEffectChance = 0, + .target = MOVE_TARGET_SELECTED, + .priority = 3, + .category = BATTLE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + }, + + [MOVE_MALIGNANT_CHAIN] = + { + .effect = EFFECT_POISON_FANG, + .power = 100, + .type = TYPE_POISON, + .accuracy = 100, + .pp = 5, + .secondaryEffectChance = 50, + .target = MOVE_TARGET_SELECTED, + .priority = 0, + .category = BATTLE_CATEGORY_SPECIAL, + }, + // Z-Moves [MOVE_BREAKNECK_BLITZ] = { diff --git a/src/data/contest_moves.h b/src/data/contest_moves.h index 608409168393..8167f2510435 100644 --- a/src/data/contest_moves.h +++ b/src/data/contest_moves.h @@ -6074,6 +6074,36 @@ const struct ContestMove gContestMoves[MOVES_COUNT] = [MOVE_SYRUP_BOMB] = {0}, // TODO [MOVE_IVY_CUDGEL] = {0}, // TODO + + [MOVE_ELECTRO_SHOT] = {0}, // TODO + + [MOVE_TERA_STARSTORM] = {0}, // TODO + + [MOVE_FICKLE_BEAM] = {0}, // TODO + + [MOVE_BURNING_BULWARK] = {0}, // TODO + + [MOVE_THUNDERCLAP] = {0}, // TODO + + [MOVE_MIGHTY_CLEAVE] = {0}, // TODO + + [MOVE_TACHYON_CUTTER] = {0}, // TODO + + [MOVE_HARD_PRESS] = {0}, // TODO + + [MOVE_DRAGON_CHEER] = {0}, // TODO + + [MOVE_ALLURING_VOICE] = {0}, // TODO + + [MOVE_TEMPER_FLARE] = {0}, // TODO + + [MOVE_SUPERCELL_SLAM] = {0}, // TODO + + [MOVE_PSYCHIC_NOISE] = {0}, // TODO + + [MOVE_UPPER_HAND] = {0}, // TODO + + [MOVE_MALIGNANT_CHAIN] = {0}, // TODO }; const struct ContestEffect gContestEffects[] = diff --git a/src/data/graphics/items.h b/src/data/graphics/items.h index f273b6d3b026..0a41ce627909 100644 --- a/src/data/graphics/items.h +++ b/src/data/graphics/items.h @@ -663,6 +663,9 @@ const u32 gItemIconPalette_UnremarkableTeacup[] = INCBIN_U32("graphics/items/ico const u32 gItemIcon_MasterpieceTeacup[] = INCBIN_U32("graphics/items/icons/masterpiece_teacup.4bpp.lz"); const u32 gItemIconPalette_MasterpieceTeacup[] = INCBIN_U32("graphics/items/icon_palettes/masterpiece_teacup.gbapal.lz"); +const u32 gItemIcon_MetalAlloy[] = INCBIN_U32("graphics/items/icons/metal_alloy.4bpp.lz"); +const u32 gItemIconPalette_MetalAlloy[] = INCBIN_U32("graphics/items/icon_palettes/metal_alloy.gbapal.lz"); + // Nectars const u32 gItemIcon_RedNectar[] = INCBIN_U32("graphics/items/icons/red_nectar.4bpp.lz"); diff --git a/src/data/item_icon_table.h b/src/data/item_icon_table.h index 33ed4aed8dcc..e048cf8d4e6d 100644 --- a/src/data/item_icon_table.h +++ b/src/data/item_icon_table.h @@ -859,6 +859,8 @@ const u32 *const gItemIconTable[ITEMS_COUNT + 1][2] = [ITEM_SWIFT_MOCHI] = {gItemIcon_Mochi, gItemIconPalette_SwiftMochi}, [ITEM_FRESH_START_MOCHI] = {gItemIcon_Mochi, gItemIconPalette_FreshStartMochi}, [ITEM_GLIMMERING_CHARM] = {gItemIcon_GlimmeringCharm, gItemIconPalette_GlimmeringCharm}, + [ITEM_METAL_ALLOY] = {gItemIcon_MetalAlloy, gItemIconPalette_MetalAlloy}, + [ITEM_STELLAR_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, //{gItemIcon_TeraShard, gItemIconPalette_StellarTeraShard}, // Return to field arrow [ITEMS_COUNT] = {gItemIcon_ReturnToFieldArrow, gItemIconPalette_ReturnToFieldArrow}, }; diff --git a/src/data/items.h b/src/data/items.h index 2114d1a4bd6b..39038cb99123 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -22,6 +22,8 @@ #define X_ITEM_STAGES (B_X_ITEMS_BUFF >= GEN_7) ? 2 : 1 +#define TREASURE_FACTOR (I_SELL_VALUE_FRACTION >= GEN_9) ? 2: 1 + // Shared Item Description entries static const u8 sFullHealDesc[] = _("Heals all the\n" @@ -185,7 +187,7 @@ const struct Item gItems[] = [ITEM_ULTRA_BALL] = { .name = _("Ultra Ball"), - .price = 800, + .price = (I_PRICE >= GEN_7) ? 800 : 1200, .description = COMPOUND_STRING("A better Ball with\n" "a higher catch rate\n" "than a Great Ball."), @@ -211,7 +213,7 @@ const struct Item gItems[] = [ITEM_PREMIER_BALL] = { .name = _("Premier Ball"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 200, .description = COMPOUND_STRING("A rare Ball made\n" "in commemoration\n" "of some event."), @@ -328,7 +330,7 @@ const struct Item gItems[] = [ITEM_LUXURY_BALL] = { .name = _("Luxury Ball"), - .price = 1000, + .price = (I_PRICE >= GEN_8) ? 3000 : 1000, .description = COMPOUND_STRING("A cozy Ball that\n" "makes Pokémon\n" "more friendly."), @@ -341,7 +343,7 @@ const struct Item gItems[] = [ITEM_LEVEL_BALL] = { .name = _("Level Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("A Ball that works\n" "well on lower\n" "level Pokémon."), @@ -354,7 +356,7 @@ const struct Item gItems[] = [ITEM_LURE_BALL] = { .name = _("Lure Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("A Ball that works\n" "well on fished\n" "up Pokémon."), @@ -367,7 +369,7 @@ const struct Item gItems[] = [ITEM_MOON_BALL] = { .name = _("Moon Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("A Ball that works\n" "well on Moon\n" "Stone users."), @@ -380,7 +382,7 @@ const struct Item gItems[] = [ITEM_FRIEND_BALL] = { .name = _("Friend Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("A Ball that makes\n" "a Pokémon friendly\n" "when caught."), @@ -393,7 +395,7 @@ const struct Item gItems[] = [ITEM_LOVE_BALL] = { .name = _("Love Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("Works well on\n" "Pokémon of the\n" "opposite gender."), @@ -406,7 +408,7 @@ const struct Item gItems[] = [ITEM_FAST_BALL] = { .name = _("Fast Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("Works well on\n" "very fast\n" "Pokémon."), @@ -419,7 +421,7 @@ const struct Item gItems[] = [ITEM_HEAVY_BALL] = { .name = _("Heavy Ball"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 300, .description = COMPOUND_STRING("Works well on\n" "very heavy\n" "Pokémon."), @@ -463,7 +465,7 @@ const struct Item gItems[] = [ITEM_SPORT_BALL] = { .name = _("Sport Ball"), - .price = 0, + .price = (I_PRICE < GEN_3 || I_PRICE >= GEN_9) ? 0 : 300, .description = COMPOUND_STRING("A special Ball used\n" "in the Bug-Catching\n" "Contest."), @@ -515,7 +517,7 @@ const struct Item gItems[] = [ITEM_POTION] = { .name = _("Potion"), - .price = 200, + .price = (I_PRICE >= GEN_7) ? 200 : 300, .holdEffectParam = 20, .description = COMPOUND_STRING("Restores the HP of\n" "a Pokémon by\n" @@ -551,7 +553,7 @@ const struct Item gItems[] = [ITEM_HYPER_POTION] = { .name = _("Hyper Potion"), - .price = 1500, + .price = (I_PRICE >= GEN_2 || I_PRICE <= GEN_6) ? 1200 : 1500, .holdEffectParam = 120, #if I_HEALTH_RECOVERY >= GEN_7 .description = COMPOUND_STRING("Restores the HP of\n" @@ -601,7 +603,7 @@ const struct Item gItems[] = [ITEM_REVIVE] = { .name = _("Revive"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 1500, .description = COMPOUND_STRING("Revives a fainted\n" "Pokémon with half\n" "its HP."), @@ -669,7 +671,7 @@ const struct Item gItems[] = [ITEM_LEMONADE] = { .name = _("Lemonade"), - .price = 400, + .price = (I_PRICE >= GEN_7) ? 400 : 350, .holdEffectParam = 70, #if I_HEALTH_RECOVERY >= GEN_7 .description = COMPOUND_STRING("A very sweet drink\n" @@ -690,7 +692,7 @@ const struct Item gItems[] = [ITEM_MOOMOO_MILK] = { .name = _("Moomoo Milk"), - .price = 600, + .price = (I_PRICE >= GEN_7) ? 600 : 500, .holdEffectParam = 100, .description = COMPOUND_STRING("A nutritious milk\n" "that restores HP\n" @@ -725,7 +727,7 @@ const struct Item gItems[] = [ITEM_ENERGY_ROOT] = { .name = _("Energy Root"), - .price = 1200, + .price = (I_PRICE >= GEN_7) ? 1200 : 800, #if I_HEALTH_RECOVERY >= GEN_7 .description = COMPOUND_STRING("A bitter root\n" "that restores HP\n" @@ -745,7 +747,7 @@ const struct Item gItems[] = [ITEM_HEAL_POWDER] = { .name = _("Heal Powder"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 450, .description = COMPOUND_STRING("A bitter powder\n" "that heals all\n" "status problems."), @@ -773,7 +775,7 @@ const struct Item gItems[] = [ITEM_ANTIDOTE] = { .name = _("Antidote"), - .price = 200, + .price = (I_PRICE >= GEN_7) ? 200 : 100, .description = COMPOUND_STRING("Heals a poisoned\n" "Pokémon."), .pocket = POCKET_ITEMS, @@ -786,7 +788,7 @@ const struct Item gItems[] = [ITEM_PARALYZE_HEAL] = { .name = _("Paralyze Heal"), - .price = 300, + .price = (I_PRICE == GEN_7) ? 300 : 200, .description = COMPOUND_STRING("Heals a paralyzed\n" "Pokémon."), .pocket = POCKET_ITEMS, @@ -799,7 +801,7 @@ const struct Item gItems[] = [ITEM_BURN_HEAL] = { .name = _("Burn Heal"), - .price = 300, + .price = (I_PRICE == GEN_7) ? 300 : ((I_PRICE <= GEN_7) ? 250 : 200), .description = COMPOUND_STRING("Heals Pokémon\n" "of a burn."), .pocket = POCKET_ITEMS, @@ -812,7 +814,7 @@ const struct Item gItems[] = [ITEM_ICE_HEAL] = { .name = _("Ice Heal"), - .price = 100, + .price = (I_PRICE == GEN_7) ? 100 : ((I_PRICE <= GEN_7) ? 250 : 200), .description = COMPOUND_STRING("Defrosts a frozen\n" "Pokémon."), .pocket = POCKET_ITEMS, @@ -825,7 +827,7 @@ const struct Item gItems[] = [ITEM_AWAKENING] = { .name = _("Awakening"), - .price = 100, + .price = (I_PRICE >= GEN_2 && I_PRICE <= GEN_6) ? 250 : ((I_PRICE == GEN_7) ? 100 : 200), .description = COMPOUND_STRING("Awakens a sleeping\n" "Pokémon."), .pocket = POCKET_ITEMS, @@ -838,7 +840,7 @@ const struct Item gItems[] = [ITEM_FULL_HEAL] = { .name = _("Full Heal"), - .price = 400, + .price = (I_PRICE >= GEN_7) ? 400 : 600, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -850,7 +852,7 @@ const struct Item gItems[] = [ITEM_ETHER] = { .name = _("Ether"), - .price = 1200, + .price = (I_PRICE >= GEN_2) ? 1200 : 1, .holdEffectParam = 10, .description = COMPOUND_STRING("Restores the PP\n" "of a selected move\n" @@ -865,7 +867,7 @@ const struct Item gItems[] = [ITEM_MAX_ETHER] = { .name = _("Max Ether"), - .price = 2000, + .price = (I_PRICE >= GEN_2) ? 2000 : 1, .holdEffectParam = 255, .description = COMPOUND_STRING("Fully restores the\n" "PP of a selected\n" @@ -880,7 +882,7 @@ const struct Item gItems[] = [ITEM_ELIXIR] = { .name = _("Elixir"), - .price = 3000, + .price = (I_PRICE >= GEN_2) ? 3000 : 1, .holdEffectParam = 10, .description = COMPOUND_STRING("Restores the PP\n" "of all moves by 10."), @@ -894,7 +896,7 @@ const struct Item gItems[] = [ITEM_MAX_ELIXIR] = { .name = _("Max Elixir"), - .price = 4500, + .price = (I_PRICE >= GEN_2) ? 4500 : 1, .holdEffectParam = 255, .description = COMPOUND_STRING("Fully restores the\n" "PP of a Pokémon's\n" @@ -909,7 +911,7 @@ const struct Item gItems[] = [ITEM_BERRY_JUICE] = { .name = _("Berry Juice"), - .price = 200, + .price = 100, .holdEffect = HOLD_EFFECT_RESTORE_HP, .holdEffectParam = 20, .description = COMPOUND_STRING("A 100% pure juice\n" @@ -925,7 +927,7 @@ const struct Item gItems[] = [ITEM_SACRED_ASH] = { .name = _("Sacred Ash"), - .price = 50000, + .price = (I_PRICE >= GEN_7) ? 50000 : 200, .description = COMPOUND_STRING("Fully revives and\n" "restores all\n" "fainted Pokémon."), @@ -938,7 +940,7 @@ const struct Item gItems[] = [ITEM_SWEET_HEART] = { .name = _("Sweet Heart"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 100, .holdEffectParam = 20, .description = COMPOUND_STRING("A sweet chocolate\n" "that restores HP\n" @@ -979,7 +981,7 @@ const struct Item gItems[] = [ITEM_RAGE_CANDY_BAR] = { .name = _("RageCandyBar"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 300, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -991,7 +993,7 @@ const struct Item gItems[] = [ITEM_LAVA_COOKIE] = { .name = _("Lava Cookie"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 200, .description = COMPOUND_STRING("A local specialty\n" "that heals all\n" "status problems."), @@ -1005,7 +1007,7 @@ const struct Item gItems[] = [ITEM_OLD_GATEAU] = { .name = _("Old Gateau"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 200, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1017,7 +1019,7 @@ const struct Item gItems[] = [ITEM_CASTELIACONE] = { .name = _("Casteliacone"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 100, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1029,7 +1031,7 @@ const struct Item gItems[] = [ITEM_LUMIOSE_GALETTE] = { .name = _("LumioseGlete"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 200, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1041,7 +1043,7 @@ const struct Item gItems[] = [ITEM_SHALOUR_SABLE] = { .name = _("ShalourSable"), - .price = 350, + .price = (I_PRICE >= GEN_7) ? 350 : 200, .description = sFullHealDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1067,7 +1069,7 @@ const struct Item gItems[] = [ITEM_HP_UP] = { .name = _("HP Up"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base HP\n" "of one Pokémon."), .pocket = POCKET_ITEMS, @@ -1079,7 +1081,7 @@ const struct Item gItems[] = [ITEM_PROTEIN] = { .name = _("Protein"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base\n" "Attack stat of one\n" "Pokémon."), @@ -1092,7 +1094,7 @@ const struct Item gItems[] = [ITEM_IRON] = { .name = _("Iron"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base\n" "Defense stat of\n" "one Pokémon."), @@ -1105,7 +1107,7 @@ const struct Item gItems[] = [ITEM_CALCIUM] = { .name = _("Calcium"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base\n" "Sp. Atk stat of one\n" "Pokémon."), @@ -1118,7 +1120,7 @@ const struct Item gItems[] = [ITEM_ZINC] = { .name = _("Zinc"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base\n" "Sp. Def stat of one\n" "Pokémon."), @@ -1131,7 +1133,7 @@ const struct Item gItems[] = [ITEM_CARBOS] = { .name = _("Carbos"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the base\n" "Speed stat of one\n" "Pokémon."), @@ -1144,7 +1146,7 @@ const struct Item gItems[] = [ITEM_PP_UP] = { .name = _("PP Up"), - .price = 10000, + .price = (I_PRICE == GEN_1) ? 1 : ((I_PRICE >= GEN_7) ? 10000 : 9800), .description = COMPOUND_STRING("Raises the maximum\n" "PP of a selected\n" "move."), @@ -1157,7 +1159,7 @@ const struct Item gItems[] = [ITEM_PP_MAX] = { .name = _("PP Max"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 9800, .description = COMPOUND_STRING("Raises the PP of a\n" "move to its maximum\n" "points."), @@ -1172,7 +1174,7 @@ const struct Item gItems[] = [ITEM_HEALTH_FEATHER] = { .name = _("HealthFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sHealthFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1183,7 +1185,7 @@ const struct Item gItems[] = [ITEM_MUSCLE_FEATHER] = { .name = _("MuscleFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sMuscleFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1194,7 +1196,7 @@ const struct Item gItems[] = [ITEM_RESIST_FEATHER] = { .name = _("ResistFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sResistFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1205,7 +1207,7 @@ const struct Item gItems[] = [ITEM_GENIUS_FEATHER] = { .name = _("GeniusFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sGeniusFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1216,7 +1218,7 @@ const struct Item gItems[] = [ITEM_CLEVER_FEATHER] = { .name = _("CleverFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sCleverFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1227,7 +1229,7 @@ const struct Item gItems[] = [ITEM_SWIFT_FEATHER] = { .name = _("SwiftFeather"), - .price = 300, + .price = (I_PRICE >= GEN_7) ? 300 : 3000, .description = sSwiftFeatherDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -1240,7 +1242,7 @@ const struct Item gItems[] = [ITEM_ABILITY_CAPSULE] = { .name = _("AbilityCapsle"), - .price = 10000, + .price = (I_PRICE < GEN_7) ? 1000 : ((I_PRICE < GEN_9) ? 10000 : 100000), .holdEffectParam = 0, .description = COMPOUND_STRING("Switches a Poké-\n" "mon's ability."), @@ -1252,7 +1254,7 @@ const struct Item gItems[] = [ITEM_ABILITY_PATCH] = { .name = _("AbilityPatch"), - .price = 0, + .price = (I_PRICE >= GEN_9) ? 250000 : 20, .holdEffectParam = 0, .description = COMPOUND_STRING("Turns the ability\n" "of a Pokémon into\n" @@ -1267,273 +1269,294 @@ const struct Item gItems[] = [ITEM_LONELY_MINT] = { .name = _("Lonely Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Attack, but\n" "reduces Defense."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_LONELY, .flingPower = 10, }, [ITEM_ADAMANT_MINT] = { .name = _("Adamant Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Attack, but\n" "reduces Sp. Atk."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_ADAMANT, .flingPower = 10, }, [ITEM_NAUGHTY_MINT] = { .name = _("Naughty Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Attack, but\n" "reduces Sp. Def."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_NAUGHTY, .flingPower = 10, }, [ITEM_BRAVE_MINT] = { .name = _("Brave Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Attack, but\n" "reduces Speed."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_BRAVE, .flingPower = 10, }, [ITEM_BOLD_MINT] = { .name = _("Bold Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Defense, but\n" "reduces Attack."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_BOLD, .flingPower = 10, }, [ITEM_IMPISH_MINT] = { .name = _("Impish Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Defense, but\n" "reduces Sp. Atk."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_IMPISH, .flingPower = 10, }, [ITEM_LAX_MINT] = { .name = _("Lax Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Defense, but\n" "reduces Sp. Def."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_LAX, .flingPower = 10, }, [ITEM_RELAXED_MINT] = { .name = _("Relaxed Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Defense, but\n" "reduces Speed."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_RELAXED, .flingPower = 10, }, [ITEM_MODEST_MINT] = { .name = _("Modest Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Atk, but\n" "reduces Attack."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_MODEST, .flingPower = 10, }, [ITEM_MILD_MINT] = { .name = _("Mild Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Atk, but\n" "reduces Defense."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_MILD, .flingPower = 10, }, [ITEM_RASH_MINT] = { .name = _("Rash Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Atk, but\n" "reduces Sp. Def."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_RASH, .flingPower = 10, }, [ITEM_QUIET_MINT] = { .name = _("Quiet Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Atk, but\n" "reduces Speed."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_QUIET, .flingPower = 10, }, [ITEM_CALM_MINT] = { .name = _("Calm Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Def, but\n" "reduces Attack."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_CALM, .flingPower = 10, }, [ITEM_GENTLE_MINT] = { .name = _("Gentle Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Def, but\n" "reduces Defense."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_GENTLE, .flingPower = 10, }, [ITEM_CAREFUL_MINT] = { .name = _("Careful Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Def, but\n" "reduces Sp. Atk."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_CAREFUL, .flingPower = 10, }, [ITEM_SASSY_MINT] = { .name = _("Sassy Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Sp. Def, but\n" "reduces Speed."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_SASSY, .flingPower = 10, }, [ITEM_TIMID_MINT] = { .name = _("Timid Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Speed, but\n" "reduces Attack."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_TIMID, .flingPower = 10, }, [ITEM_HASTY_MINT] = { .name = _("Hasty Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Speed, but\n" "reduces Defense."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_HASTY, .flingPower = 10, }, [ITEM_JOLLY_MINT] = { .name = _("Jolly Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Speed, but\n" "reduces Sp. Atk."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_JOLLY, .flingPower = 10, }, [ITEM_NAIVE_MINT] = { .name = _("Naive Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "ups Speed, but\n" "reduces Sp. Def."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_NAIVE, .flingPower = 10, }, [ITEM_SERIOUS_MINT] = { .name = _("Serious Mint"), - .price = 20, + .price = (I_PRICE >= GEN_9) ? 20000 : 20, .description = COMPOUND_STRING("Can be smelled. It\n" "makes each stat\n" "grow equally."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_Mint, + .secondaryId = NATURE_SERIOUS, .flingPower = 10, }, @@ -1542,7 +1565,7 @@ const struct Item gItems[] = [ITEM_RARE_CANDY] = { .name = _("Rare Candy"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 4800, .description = COMPOUND_STRING("Raises the level\n" "of a Pokémon by\n" "one."), @@ -1630,8 +1653,8 @@ const struct Item gItems[] = "Level of a single\n" "Pokémon by one."), .pocket = POCKET_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_DynamaxCandy, .flingPower = 30, }, @@ -1640,7 +1663,7 @@ const struct Item gItems[] = [ITEM_BLUE_FLUTE] = { .name = _("Blue Flute"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 100, .description = COMPOUND_STRING("A glass flute that\n" "awakens sleeping\n" "Pokémon."), @@ -1654,7 +1677,7 @@ const struct Item gItems[] = [ITEM_YELLOW_FLUTE] = { .name = _("Yellow Flute"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 300, .description = COMPOUND_STRING("A glass flute that\n" "snaps Pokémon\n" "out of confusion."), @@ -1668,7 +1691,7 @@ const struct Item gItems[] = [ITEM_RED_FLUTE] = { .name = _("Red Flute"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 200, .description = COMPOUND_STRING("A glass flute that\n" "snaps Pokémon\n" "out of attraction."), @@ -1684,7 +1707,7 @@ const struct Item gItems[] = [ITEM_BLACK_FLUTE] = { .name = _("Black Flute"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 400, .holdEffectParam = 50, .description = COMPOUND_STRING("A glass flute that\n" "keeps away wild\n" @@ -1698,7 +1721,7 @@ const struct Item gItems[] = [ITEM_WHITE_FLUTE] = { .name = _("White Flute"), - .price = 20, + .price = (I_PRICE >= GEN_7) ? 20 : 500, .holdEffectParam = 150, .description = COMPOUND_STRING("A glass flute that\n" "lures wild Pokémon."), @@ -1713,7 +1736,7 @@ const struct Item gItems[] = [ITEM_REPEL] = { .name = _("Repel"), - .price = 400, + .price = (I_PRICE >= GEN_7) ? 400 : 350, .holdEffectParam = 100, .description = COMPOUND_STRING("Repels weak wild\n" "Pokémon for 100\n" @@ -1727,7 +1750,7 @@ const struct Item gItems[] = [ITEM_SUPER_REPEL] = { .name = _("Super Repel"), - .price = 700, + .price = (I_PRICE >= GEN_7) ? 700 : 500, .holdEffectParam = 200, .description = COMPOUND_STRING("Repels weak wild\n" "Pokémon for 200\n" @@ -1741,7 +1764,7 @@ const struct Item gItems[] = [ITEM_MAX_REPEL] = { .name = _("Max Repel"), - .price = 900, + .price = (I_PRICE >= GEN_7) ? 900 : 700, .holdEffectParam = 250, .description = COMPOUND_STRING("Repels weak wild\n" "Pokémon for 250\n" @@ -1808,7 +1831,7 @@ const struct Item gItems[] = .importance = 1, .pocket = POCKET_KEY_ITEMS, #else - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 550, .pocket = POCKET_ITEMS, #endif .type = ITEM_USE_FIELD, @@ -1821,7 +1844,7 @@ const struct Item gItems[] = [ITEM_X_ATTACK] = { .name = _("X Attack"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 500, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises stat\n" @@ -1842,7 +1865,7 @@ const struct Item gItems[] = [ITEM_X_DEFENSE] = { .name = _("X Defense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 550, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises stat\n" @@ -1863,7 +1886,7 @@ const struct Item gItems[] = [ITEM_X_SP_ATK] = { .name = _("X Sp. Atk"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 350, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises stat\n" @@ -1884,7 +1907,7 @@ const struct Item gItems[] = [ITEM_X_SP_DEF] = { .name = _("X Sp. Def"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 350, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises stat\n" @@ -1905,7 +1928,7 @@ const struct Item gItems[] = [ITEM_X_SPEED] = { .name = _("X Speed"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 350, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises stat\n" @@ -1926,7 +1949,7 @@ const struct Item gItems[] = [ITEM_X_ACCURACY] = { .name = _("X Accuracy"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 950, .holdEffectParam = X_ITEM_STAGES, #if B_X_ITEMS_BUFF >= GEN_7 .description = COMPOUND_STRING("Sharply raises move\n" @@ -1947,7 +1970,7 @@ const struct Item gItems[] = [ITEM_DIRE_HIT] = { .name = _("Dire Hit"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 650, .description = COMPOUND_STRING("Raises the\n" "critical-hit ratio\n" "during one battle."), @@ -1961,7 +1984,7 @@ const struct Item gItems[] = [ITEM_GUARD_SPEC] = { .name = _("Guard Spec."), - .price = 1500, + .price = (I_PRICE >= GEN_7) ? 1500 : 700, .description = COMPOUND_STRING("Prevents stat\n" "reduction when\n" "used in battle."), @@ -1975,7 +1998,7 @@ const struct Item gItems[] = [ITEM_POKE_DOLL] = { .name = _("Poké Doll"), - .price = 100, + .price = (I_PRICE < GEN_7) ? 1000 : ((I_PRICE == GEN_7) ? 100 : 300), .description = sPokeDollDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -1987,7 +2010,7 @@ const struct Item gItems[] = [ITEM_FLUFFY_TAIL] = { .name = _("Fluffy Tail"), - .price = 100, + .price = (I_PRICE >= GEN_7) ? 100 : 1000, .description = sPokeDollDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -1999,7 +2022,7 @@ const struct Item gItems[] = [ITEM_POKE_TOY] = { .name = _("Poké Toy"), - .price = 100, + .price = (I_PRICE >= GEN_7) ? 100 : 1000, .description = sPokeDollDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2027,7 +2050,7 @@ const struct Item gItems[] = [ITEM_BOTTLE_CAP] = { .name = _("Bottle Cap"), - .price = 5000, + .price = (I_PRICE >= GEN_9) ? 20000 : 5000, .description = COMPOUND_STRING("A beautiful bottle\n" "cap that gives off\n" "a silver gleam."), @@ -2040,7 +2063,7 @@ const struct Item gItems[] = [ITEM_GOLD_BOTTLE_CAP] = { .name = _("GoldBottlCap"), - .price = 10000, + .price = (I_PRICE >= GEN_9) ? 60000 : 10000, .description = COMPOUND_STRING("A beautiful bottle\n" "cap that gives off\n" "a golden gleam."), @@ -2053,7 +2076,7 @@ const struct Item gItems[] = [ITEM_NUGGET] = { .name = _("Nugget"), - .price = 10000, + .price = 10000 * TREASURE_FACTOR, .description = COMPOUND_STRING("A nugget of pure\n" "gold. Can be sold at\n" "a high price."), @@ -2066,7 +2089,7 @@ const struct Item gItems[] = [ITEM_BIG_NUGGET] = { .name = _("Big Nugget"), - .price = 40000, + .price = (I_PRICE >= GEN_7) ? (40000 * TREASURE_FACTOR) : 20000, .description = COMPOUND_STRING("A big nugget made\n" "of gold, sellable\n" "at a high price."), @@ -2079,7 +2102,7 @@ const struct Item gItems[] = [ITEM_TINY_MUSHROOM] = { .name = _("Tiny Mushroom"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A plain mushroom\n" "that would sell\n" "at a cheap price."), @@ -2092,7 +2115,7 @@ const struct Item gItems[] = [ITEM_BIG_MUSHROOM] = { .name = _("Big Mushroom"), - .price = 5000, + .price = 5000 * TREASURE_FACTOR, .description = sBigMushroomDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2103,7 +2126,7 @@ const struct Item gItems[] = [ITEM_BALM_MUSHROOM] = { .name = _("Balm Mushroom"), - .price = 15000, + .price = (I_PRICE >= GEN_7) ? 15000 * TREASURE_FACTOR: 12500, .description = sBigMushroomDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2114,7 +2137,7 @@ const struct Item gItems[] = [ITEM_PEARL] = { .name = _("Pearl"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR: 1400, .description = COMPOUND_STRING("A pretty pearl\n" "that would sell at a\n" "cheap price."), @@ -2127,7 +2150,7 @@ const struct Item gItems[] = [ITEM_BIG_PEARL] = { .name = _("Big Pearl"), - .price = 8000, + .price = (I_PRICE >= GEN_7) ? 8000 * TREASURE_FACTOR: 7500, .description = COMPOUND_STRING("A lovely large pearl\n" "that would sell at a\n" "high price."), @@ -2140,7 +2163,7 @@ const struct Item gItems[] = [ITEM_PEARL_STRING] = { .name = _("Pearl String"), - .price = 20000, + .price = (I_PRICE >= GEN_8) ? 15000 * TREASURE_FACTOR: ((I_PRICE == GEN_7) ? 30000 : 15000), .description = COMPOUND_STRING("Very large pearls\n" "that would sell at a\n" "high price."), @@ -2153,7 +2176,7 @@ const struct Item gItems[] = [ITEM_STARDUST] = { .name = _("Stardust"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 * TREASURE_FACTOR: 2000, .description = COMPOUND_STRING("Beautiful red sand.\n" "Can be sold at a\n" "high price."), @@ -2166,7 +2189,7 @@ const struct Item gItems[] = [ITEM_STAR_PIECE] = { .name = _("Star Piece"), - .price = 12000, + .price = (I_PRICE >= GEN_7) ? 12000 * TREASURE_FACTOR: 9800, .description = COMPOUND_STRING("A red gem shard.\n" "It would sell for a\n" "very high price."), @@ -2179,7 +2202,7 @@ const struct Item gItems[] = [ITEM_COMET_SHARD] = { .name = _("Comet Shard"), - .price = 25000, + .price = (I_PRICE <= GEN_5) ? 0 : ((I_PRICE == GEN_6) ? 30000 : ((I_PRICE == GEN_7) ? 60000 : 25000 * TREASURE_FACTOR)), .description = COMPOUND_STRING("A comet's shard.\n" "It would sell for a\n" "high price."), @@ -2218,7 +2241,7 @@ const struct Item gItems[] = [ITEM_RED_SHARD] = { .name = _("Red Shard"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 200, .description = sShardsDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2229,7 +2252,7 @@ const struct Item gItems[] = [ITEM_BLUE_SHARD] = { .name = _("Blue Shard"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 200, .description = sShardsDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2240,7 +2263,7 @@ const struct Item gItems[] = [ITEM_YELLOW_SHARD] = { .name = _("Yellow Shard"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 200, .description = sShardsDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2251,7 +2274,7 @@ const struct Item gItems[] = [ITEM_GREEN_SHARD] = { .name = _("Green Shard"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 200, .description = sShardsDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, @@ -2275,7 +2298,7 @@ const struct Item gItems[] = [ITEM_HONEY] = { .name = _("Honey"), - .price = 300, + .price = (I_PRICE < GEN_5) ? 100 : ((I_PRICE < GEN_8) ? 300 : 900), .description = COMPOUND_STRING("Sweet honey that\n" "attracts wild\n" "Pokémon when used."), @@ -2288,7 +2311,7 @@ const struct Item gItems[] = [ITEM_RARE_BONE] = { .name = _("Rare Bone"), - .price = 5000, + .price = (I_PRICE >= GEN_7) ? 5000 * TREASURE_FACTOR: 10000, .description = COMPOUND_STRING("A very rare bone.\n" "It can be sold at\n" "a high price."), @@ -2314,7 +2337,7 @@ const struct Item gItems[] = [ITEM_PRETTY_FEATHER] = { .name = _("PrettyFeather"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 * TREASURE_FACTOR: 200, .description = COMPOUND_STRING("A beautiful yet\n" "plain feather that\n" "does nothing."), @@ -2418,7 +2441,7 @@ const struct Item gItems[] = [ITEM_STRANGE_SOUVENIR] = { .name = _("StrngeSouvnr"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 10, .description = COMPOUND_STRING("An ornament that\n" "depicts a Pokémon\n" "from Alola."), @@ -2437,7 +2460,7 @@ const struct Item gItems[] = "ancient marine\n" "Pokémon's seashell."), #if I_KEY_FOSSILS >= GEN_4 - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .pocket = POCKET_ITEMS, #else .price = 0, @@ -2456,7 +2479,7 @@ const struct Item gItems[] = "ancient marine\n" "Pokémon's shell."), #if I_KEY_FOSSILS >= GEN_4 - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .pocket = POCKET_ITEMS, #else .price = 0, @@ -2475,7 +2498,7 @@ const struct Item gItems[] = "the genes of an\n" "ancient Pokémon."), #if I_KEY_FOSSILS >= GEN_4 - .price = 10000, + .price = 1000, .pocket = POCKET_ITEMS, #else .price = 0, @@ -2492,7 +2515,7 @@ const struct Item gItems[] = .name = _("Root Fossil"), .description = sRootFossilDesc, #if I_KEY_FOSSILS >= GEN_4 - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .pocket = POCKET_ITEMS, #else .price = 0, @@ -2509,7 +2532,7 @@ const struct Item gItems[] = .name = _("Claw Fossil"), .description = sRootFossilDesc, #if I_KEY_FOSSILS >= GEN_4 - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .pocket = POCKET_ITEMS, #else .price = 0, @@ -2524,7 +2547,7 @@ const struct Item gItems[] = [ITEM_ARMOR_FOSSIL] = { .name = _("Armor Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a\n" "prehistoric Poké-\n" "mon's head."), @@ -2537,7 +2560,7 @@ const struct Item gItems[] = [ITEM_SKULL_FOSSIL] = { .name = _("Skull Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a\n" "prehistoric Poké-\n" "mon's collar."), @@ -2550,7 +2573,7 @@ const struct Item gItems[] = [ITEM_COVER_FOSSIL] = { .name = _("Cover Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a\n" "prehistoric Poké-\n" "mon's back."), @@ -2563,7 +2586,7 @@ const struct Item gItems[] = [ITEM_PLUME_FOSSIL] = { .name = _("Plume Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a\n" "prehistoric Poké-\n" "mon's wing."), @@ -2576,7 +2599,7 @@ const struct Item gItems[] = [ITEM_JAW_FOSSIL] = { .name = _("Jaw Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a prehis-\n" "toric Pokémon's\n" "large jaw."), @@ -2589,7 +2612,7 @@ const struct Item gItems[] = [ITEM_SAIL_FOSSIL] = { .name = _("Sail Fossil"), - .price = 7000, + .price = (I_PRICE >= GEN_7) ? 7000: 1000, .description = COMPOUND_STRING("A piece of a prehis-\n" "toric Pokémon's\n" "skin sail."), @@ -2758,7 +2781,7 @@ const struct Item gItems[] = [ITEM_RED_APRICORN] = { .name = _("Red Apricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A red apricorn.\n" "It assails your\n" "nostrils."), @@ -2770,7 +2793,7 @@ const struct Item gItems[] = [ITEM_BLUE_APRICORN] = { .name = _("Blue Apricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A blue apricorn.\n" "It smells a bit\n" "like grass."), @@ -2782,7 +2805,7 @@ const struct Item gItems[] = [ITEM_YELLOW_APRICORN] = { .name = _("YellwApricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A yellow apricorn.\n" "It has an invigor-\n" "ating scent."), @@ -2794,7 +2817,7 @@ const struct Item gItems[] = [ITEM_GREEN_APRICORN] = { .name = _("GreenApricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A green apricorn.\n" "It has a strange,\n" "aromatic scent."), @@ -2806,7 +2829,7 @@ const struct Item gItems[] = [ITEM_PINK_APRICORN] = { .name = _("Pink Apricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A pink apricorn.\n" "It has a nice,\n" "sweet scent."), @@ -2818,7 +2841,7 @@ const struct Item gItems[] = [ITEM_WHITE_APRICORN] = { .name = _("WhiteApricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A white apricorn.\n" "It doesn't smell\n" "like anything."), @@ -2830,7 +2853,7 @@ const struct Item gItems[] = [ITEM_BLACK_APRICORN] = { .name = _("BlackApricorn"), - .price = 200, + .price = (I_PRICE == GEN_4) ? 0 : ((I_PRICE >= GEN_5 && I_PRICE <= GEN_7) ? 20 : 200), .description = COMPOUND_STRING("A black apricorn.\n" "It has an inde-\n" "scribable scent."), @@ -2855,7 +2878,7 @@ const struct Item gItems[] = [ITEM_GALARICA_TWIG] = { .name = _("GalaricaTwig"), - .price = 40, + .price = 20 * TREASURE_FACTOR, .description = COMPOUND_STRING("A twig from a tree\n" "in Galar called\n" "Galarica."), @@ -2868,7 +2891,7 @@ const struct Item gItems[] = [ITEM_ARMORITE_ORE] = { .name = _("Armorite Ore"), - .price = 40, + .price = 20, .description = COMPOUND_STRING("A rare ore. Can be\n" "found in the Isle\n" "of Armor at Galar."), @@ -3050,7 +3073,7 @@ const struct Item gItems[] = [ITEM_FIRE_STONE] = { .name = _("Fire Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3061,7 +3084,7 @@ const struct Item gItems[] = [ITEM_WATER_STONE] = { .name = _("Water Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3072,7 +3095,7 @@ const struct Item gItems[] = [ITEM_THUNDER_STONE] = { .name = _("Thunder Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3083,7 +3106,7 @@ const struct Item gItems[] = [ITEM_LEAF_STONE] = { .name = _("Leaf Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3094,7 +3117,7 @@ const struct Item gItems[] = [ITEM_ICE_STONE] = { .name = _("Ice Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3105,7 +3128,7 @@ const struct Item gItems[] = [ITEM_SUN_STONE] = { .name = _("Sun Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3116,7 +3139,7 @@ const struct Item gItems[] = [ITEM_MOON_STONE] = { .name = _("Moon Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3127,7 +3150,7 @@ const struct Item gItems[] = [ITEM_SHINY_STONE] = { .name = _("Shiny Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3138,7 +3161,7 @@ const struct Item gItems[] = [ITEM_DUSK_STONE] = { .name = _("Dusk Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3149,7 +3172,7 @@ const struct Item gItems[] = [ITEM_DAWN_STONE] = { .name = _("Dawn Stone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 2100, .description = sEvolutionStoneDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, @@ -3212,7 +3235,7 @@ const struct Item gItems[] = [ITEM_GALARICA_CUFF] = { .name = _("GalaricaCuff"), - .price = 6000, + .price = (I_PRICE >= GEN_9) ? 3000 : 6000, .description = COMPOUND_STRING("A cuff from Galar\n" "that makes certain\n" "Pokémon evolve."), @@ -3225,7 +3248,7 @@ const struct Item gItems[] = [ITEM_GALARICA_WREATH] = { .name = _("GalrcaWreath"), - .price = 6000, + .price = (I_PRICE >= GEN_9) ? 3000 : 6000, .description = COMPOUND_STRING("A wreath made in\n" "Galar. Makes some\n" "Pokémon evolve."), @@ -3238,7 +3261,7 @@ const struct Item gItems[] = [ITEM_DRAGON_SCALE] = { .name = _("Dragon Scale"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .holdEffect = HOLD_EFFECT_DRAGON_SCALE, .holdEffectParam = 10, .description = COMPOUND_STRING("A strange scale\n" @@ -3253,7 +3276,7 @@ const struct Item gItems[] = [ITEM_UPGRADE] = { .name = _("Upgrade"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .holdEffect = HOLD_EFFECT_UPGRADE, .description = COMPOUND_STRING("A peculiar box made\n" "by Silph Co."), @@ -3266,7 +3289,7 @@ const struct Item gItems[] = [ITEM_PROTECTOR] = { .name = _("Protector"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("Loved by a certain\n" "Pokémon. It's stiff\n" "and heavy."), @@ -3279,7 +3302,7 @@ const struct Item gItems[] = [ITEM_ELECTIRIZER] = { .name = _("Electirizer"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("Loved by a certain\n" "Pokémon. It's full\n" "of electric energy."), @@ -3292,7 +3315,7 @@ const struct Item gItems[] = [ITEM_MAGMARIZER] = { .name = _("Magmarizer"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("Loved by a certain\n" "Pokémon. It's full\n" "of magma energy."), @@ -3305,7 +3328,7 @@ const struct Item gItems[] = [ITEM_DUBIOUS_DISC] = { .name = _("Dubious Disc"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("A transparent device\n" "overflowing with\n" "dubious data."), @@ -3318,7 +3341,7 @@ const struct Item gItems[] = [ITEM_REAPER_CLOTH] = { .name = _("Reaper Cloth"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("Loved by a certain\n" "Pokémon. Imbued with\n" "spiritual energy."), @@ -3331,7 +3354,7 @@ const struct Item gItems[] = [ITEM_PRISM_SCALE] = { .name = _("Prism Scale"), - .price = 2000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 2000 : 500), .description = COMPOUND_STRING("A mysterious scale\n" "that evolves certain\n" "Pokémon. It shines."), @@ -3344,7 +3367,7 @@ const struct Item gItems[] = [ITEM_WHIPPED_DREAM] = { .name = _("Whipped Dream"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("A soft and sweet\n" "treat loved by\n" "a certain Pokémon."), @@ -3357,7 +3380,7 @@ const struct Item gItems[] = [ITEM_SACHET] = { .name = _("Sachet"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 * TREASURE_FACTOR : 2100, .description = COMPOUND_STRING("A sachet filled with\n" "perfumes loved by\n" "a certain Pokémon."), @@ -3370,7 +3393,7 @@ const struct Item gItems[] = [ITEM_OVAL_STONE] = { .name = _("Oval Stone"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 2100, .description = COMPOUND_STRING("Makes a certain\n" "Pokémon evolve. It's\n" "shaped like an egg."), @@ -3383,7 +3406,7 @@ const struct Item gItems[] = [ITEM_STRAWBERRY_SWEET] = { .name = _("StrwbrySweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("Strawberry-shaped\n" "sweet loved by\n" "Milcery."), @@ -3396,7 +3419,7 @@ const struct Item gItems[] = [ITEM_LOVE_SWEET] = { .name = _("Love Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A heart-shaped\n" "sweet loved by\n" "Milcery."), @@ -3409,7 +3432,7 @@ const struct Item gItems[] = [ITEM_BERRY_SWEET] = { .name = _("Berry Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A berry-shaped\n" "sweet loved by\n" "Milcery."), @@ -3422,7 +3445,7 @@ const struct Item gItems[] = [ITEM_CLOVER_SWEET] = { .name = _("Clover Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A clover-shaped\n" "sweet loved by\n" "Milcery."), @@ -3435,7 +3458,7 @@ const struct Item gItems[] = [ITEM_FLOWER_SWEET] = { .name = _("Flower Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A flower-shaped\n" "sweet loved by\n" "Milcery."), @@ -3448,7 +3471,7 @@ const struct Item gItems[] = [ITEM_STAR_SWEET] = { .name = _("Star Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A star-shaped\n" "sweet loved by\n" "Milcery."), @@ -3461,7 +3484,7 @@ const struct Item gItems[] = [ITEM_RIBBON_SWEET] = { .name = _("Ribbon Sweet"), - .price = 500, + .price = 500 * TREASURE_FACTOR, .description = COMPOUND_STRING("A ribbon-shaped\n" "sweet loved by\n" "Milcery."), @@ -3474,7 +3497,7 @@ const struct Item gItems[] = [ITEM_EVERSTONE] = { .name = _("Everstone"), - .price = 3000, + .price = (I_PRICE >= GEN_7) ? 3000 : 200, .holdEffect = HOLD_EFFECT_PREVENT_EVOLVE, .description = COMPOUND_STRING("A wondrous hold\n" "item that prevents\n" @@ -3814,7 +3837,7 @@ const struct Item gItems[] = [ITEM_DOUSE_DRIVE] = { .name = _("Douse Drive"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 1000, .holdEffect = HOLD_EFFECT_DRIVE, .description = COMPOUND_STRING("Changes Genesect's\n" "Techno Blast to\n" @@ -3829,7 +3852,7 @@ const struct Item gItems[] = [ITEM_SHOCK_DRIVE] = { .name = _("Shock Drive"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 1000, .holdEffect = HOLD_EFFECT_DRIVE, .description = COMPOUND_STRING("Changes Genesect's\n" "Techno Blast to\n" @@ -3844,7 +3867,7 @@ const struct Item gItems[] = [ITEM_BURN_DRIVE] = { .name = _("Burn Drive"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 1000, .holdEffect = HOLD_EFFECT_DRIVE, .description = COMPOUND_STRING("Changes Genesect's\n" "Techno Blast to\n" @@ -3859,7 +3882,7 @@ const struct Item gItems[] = [ITEM_CHILL_DRIVE] = { .name = _("Chill Drive"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 1000, .holdEffect = HOLD_EFFECT_DRIVE, .description = COMPOUND_STRING("Changes Genesect's\n" "Techno Blast to\n" @@ -4854,7 +4877,7 @@ const struct Item gItems[] = [ITEM_NORMAL_GEM] = { .name = _("Normal Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4869,7 +4892,7 @@ const struct Item gItems[] = [ITEM_FIRE_GEM] = { .name = _("Fire Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4884,7 +4907,7 @@ const struct Item gItems[] = [ITEM_WATER_GEM] = { .name = _("Water Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4899,7 +4922,7 @@ const struct Item gItems[] = [ITEM_ELECTRIC_GEM] = { .name = _("Electric Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4914,7 +4937,7 @@ const struct Item gItems[] = [ITEM_GRASS_GEM] = { .name = _("Grass Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4929,7 +4952,7 @@ const struct Item gItems[] = [ITEM_ICE_GEM] = { .name = _("Ice Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4944,7 +4967,7 @@ const struct Item gItems[] = [ITEM_FIGHTING_GEM] = { .name = _("Fighting Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4959,7 +4982,7 @@ const struct Item gItems[] = [ITEM_POISON_GEM] = { .name = _("Poison Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4974,7 +4997,7 @@ const struct Item gItems[] = [ITEM_GROUND_GEM] = { .name = _("Ground Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -4989,7 +5012,7 @@ const struct Item gItems[] = [ITEM_FLYING_GEM] = { .name = _("Flying Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5004,7 +5027,7 @@ const struct Item gItems[] = [ITEM_PSYCHIC_GEM] = { .name = _("Psychic Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5019,7 +5042,7 @@ const struct Item gItems[] = [ITEM_BUG_GEM] = { .name = _("Bug Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5034,7 +5057,7 @@ const struct Item gItems[] = [ITEM_ROCK_GEM] = { .name = _("Rock Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5049,7 +5072,7 @@ const struct Item gItems[] = [ITEM_GHOST_GEM] = { .name = _("Ghost Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5064,7 +5087,7 @@ const struct Item gItems[] = [ITEM_DRAGON_GEM] = { .name = _("Dragon Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5079,7 +5102,7 @@ const struct Item gItems[] = [ITEM_DARK_GEM] = { .name = _("Dark Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5094,7 +5117,7 @@ const struct Item gItems[] = [ITEM_STEEL_GEM] = { .name = _("Steel Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5109,7 +5132,7 @@ const struct Item gItems[] = [ITEM_FAIRY_GEM] = { .name = _("Fairy Gem"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GEMS, .holdEffectParam = GEM_BOOST_PARAM, .description = COMPOUND_STRING("Increases the\n" @@ -5618,7 +5641,7 @@ const struct Item gItems[] = [ITEM_LIGHT_BALL] = { .name = _("Light Ball"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 100, .holdEffect = HOLD_EFFECT_LIGHT_BALL, .description = COMPOUND_STRING("A hold item that\n" "raises the Atk and\n" @@ -5632,7 +5655,7 @@ const struct Item gItems[] = [ITEM_LEEK] = { .name = _("Leek"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 200, .holdEffect = HOLD_EFFECT_LEEK, .description = COMPOUND_STRING("A hold item that\n" "raises Farfetch'd's\n" @@ -5646,7 +5669,7 @@ const struct Item gItems[] = [ITEM_THICK_CLUB] = { .name = _("Thick Club"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 500, .holdEffect = HOLD_EFFECT_THICK_CLUB, .description = COMPOUND_STRING("A hold item that \n" "raises Cubone or\n" @@ -5660,7 +5683,7 @@ const struct Item gItems[] = [ITEM_LUCKY_PUNCH] = { .name = _("Lucky Punch"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 10, .holdEffect = HOLD_EFFECT_LUCKY_PUNCH, .description = COMPOUND_STRING("A hold item that\n" "raises Chansey's\n" @@ -5674,7 +5697,7 @@ const struct Item gItems[] = [ITEM_METAL_POWDER] = { .name = _("Metal Powder"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 10, .holdEffect = HOLD_EFFECT_METAL_POWDER, .description = COMPOUND_STRING("A hold item that\n" "raises Ditto's\n" @@ -5688,7 +5711,7 @@ const struct Item gItems[] = [ITEM_QUICK_POWDER] = { .name = _("Quick Powder"), - .price = 1000, + .price = (I_PRICE >= GEN_7) ? 1000 : 10, .holdEffect = HOLD_EFFECT_QUICK_POWDER, .description = COMPOUND_STRING("An item to be held\n" "by Ditto. This odd\n" @@ -5702,7 +5725,7 @@ const struct Item gItems[] = [ITEM_DEEP_SEA_SCALE] = { .name = _("DeepSeaScale"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 200, .holdEffect = HOLD_EFFECT_DEEP_SEA_SCALE, .description = COMPOUND_STRING("A hold item that\n" "raises the Sp. Def\n" @@ -5716,7 +5739,7 @@ const struct Item gItems[] = [ITEM_DEEP_SEA_TOOTH] = { .name = _("DeepSeaTooth"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 200, .holdEffect = HOLD_EFFECT_DEEP_SEA_TOOTH, .description = COMPOUND_STRING("A hold item that\n" "raises the Sp. Atk\n" @@ -5730,7 +5753,7 @@ const struct Item gItems[] = [ITEM_SOUL_DEW] = { .name = _("Soul Dew"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 200, .holdEffect = HOLD_EFFECT_SOUL_DEW, .holdEffectParam = B_SOUL_DEW_BOOST >= GEN_7 ? 20 : 50, #if B_SOUL_DEW_BOOST >= GEN_7 @@ -5751,7 +5774,7 @@ const struct Item gItems[] = [ITEM_ADAMANT_ORB] = { .name = _("Adamant Orb"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 10000, .holdEffect = HOLD_EFFECT_ADAMANT_ORB, .holdEffectParam = 20, .description = COMPOUND_STRING("Boosts the power of\n" @@ -5766,7 +5789,7 @@ const struct Item gItems[] = [ITEM_LUSTROUS_ORB] = { .name = _("Lustrous Orb"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 10000, .holdEffect = HOLD_EFFECT_LUSTROUS_ORB, .holdEffectParam = 20, .description = COMPOUND_STRING("Boosts the power of\n" @@ -5781,7 +5804,7 @@ const struct Item gItems[] = [ITEM_GRISEOUS_ORB] = { .name = _("Griseous Orb"), - .price = 0, + .price = (I_PRICE >= GEN_7) ? 0 : 10000, .holdEffect = HOLD_EFFECT_GRISEOUS_ORB, .holdEffectParam = 20, .description = COMPOUND_STRING("Powers up Giratina's\n" @@ -5798,7 +5821,7 @@ const struct Item gItems[] = [ITEM_SEA_INCENSE] = { .name = _("Sea Incense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 9600, .holdEffect = HOLD_EFFECT_WATER_POWER, .holdEffectParam = 20, .description = sSeaIncenseDesc, @@ -5811,7 +5834,7 @@ const struct Item gItems[] = [ITEM_LAX_INCENSE] = { .name = _("Lax Incense"), - .price = 5000, + .price = (I_PRICE >= GEN_7) ? 5000 : 9600, .holdEffect = HOLD_EFFECT_EVASION_UP, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -5826,7 +5849,7 @@ const struct Item gItems[] = [ITEM_ODD_INCENSE] = { .name = _("Odd Incense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 9600, .holdEffect = HOLD_EFFECT_PSYCHIC_POWER, .holdEffectParam = 20, .description = sOddIncenseDesc, @@ -5839,7 +5862,7 @@ const struct Item gItems[] = [ITEM_ROCK_INCENSE] = { .name = _("Rock Incense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 9600, .holdEffect = HOLD_EFFECT_ROCK_POWER, .holdEffectParam = 20, .description = sRockIncenseDesc, @@ -5852,7 +5875,7 @@ const struct Item gItems[] = [ITEM_FULL_INCENSE] = { .name = _("Full Incense"), - .price = 5000, + .price = (I_PRICE >= GEN_7) ? 5000 : 9600, .holdEffect = HOLD_EFFECT_LAGGING_TAIL, .holdEffectParam = 5, .description = sFullIncenseDesc, @@ -5865,7 +5888,7 @@ const struct Item gItems[] = [ITEM_WAVE_INCENSE] = { .name = _("Wave Incense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 9600, .holdEffect = HOLD_EFFECT_WATER_POWER, .holdEffectParam = 20, .description = sSeaIncenseDesc, @@ -5878,7 +5901,7 @@ const struct Item gItems[] = [ITEM_ROSE_INCENSE] = { .name = _("Rose Incense"), - .price = 2000, + .price = (I_PRICE >= GEN_7) ? 2000 : 9600, .holdEffect = HOLD_EFFECT_GRASS_POWER, .holdEffectParam = 20, .description = sRoseIncenseDesc, @@ -5891,7 +5914,7 @@ const struct Item gItems[] = [ITEM_LUCK_INCENSE] = { .name = _("Luck Incense"), - .price = 11000, + .price = (I_PRICE >= GEN_7) ? 11000 : 9600, .holdEffect = HOLD_EFFECT_DOUBLE_PRIZE, .description = sLuckIncenseDesc, .pocket = POCKET_ITEMS, @@ -5903,7 +5926,7 @@ const struct Item gItems[] = [ITEM_PURE_INCENSE] = { .name = _("Pure Incense"), - .price = 6000, + .price = (I_PRICE >= GEN_7) ? 6000 : 9600, .holdEffect = HOLD_EFFECT_REPEL, .description = sPureIncenseDesc, .pocket = POCKET_ITEMS, @@ -5998,7 +6021,7 @@ const struct Item gItems[] = [ITEM_POWER_WEIGHT] = { .name = _("Power Weight"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("A hold item that\n" @@ -6014,7 +6037,7 @@ const struct Item gItems[] = [ITEM_POWER_BRACER] = { .name = _("Power Bracer"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("A hold item that\n" @@ -6030,7 +6053,7 @@ const struct Item gItems[] = [ITEM_POWER_BELT] = { .name = _("Power Belt"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("A hold item that\n" @@ -6046,7 +6069,7 @@ const struct Item gItems[] = [ITEM_POWER_LENS] = { .name = _("Power Lens"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("Hold item that pro-\n" @@ -6062,7 +6085,7 @@ const struct Item gItems[] = [ITEM_POWER_BAND] = { .name = _("Power Band"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("Hold item that pro-\n" @@ -6078,7 +6101,7 @@ const struct Item gItems[] = [ITEM_POWER_ANKLET] = { .name = _("Power Anklet"), - .price = 3000, + .price = (I_PRICE >= GEN_9) ? 10000 : 3000, .holdEffect = HOLD_EFFECT_POWER_ITEM, .holdEffectParam = 8, .description = COMPOUND_STRING("A hold item that\n" @@ -6096,7 +6119,7 @@ const struct Item gItems[] = [ITEM_SILK_SCARF] = { .name = _("Silk Scarf"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_NORMAL_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6111,7 +6134,7 @@ const struct Item gItems[] = [ITEM_CHARCOAL] = { .name = _("Charcoal"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 9800), .holdEffect = HOLD_EFFECT_FIRE_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6126,7 +6149,7 @@ const struct Item gItems[] = [ITEM_MYSTIC_WATER] = { .name = _("Mystic Water"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_WATER_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6141,7 +6164,7 @@ const struct Item gItems[] = [ITEM_MAGNET] = { .name = _("Magnet"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_ELECTRIC_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6156,7 +6179,7 @@ const struct Item gItems[] = [ITEM_MIRACLE_SEED] = { .name = _("Miracle Seed"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_GRASS_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = sRoseIncenseDesc, @@ -6169,7 +6192,7 @@ const struct Item gItems[] = [ITEM_NEVER_MELT_ICE] = { .name = _("Never-MeltIce"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_ICE_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6184,7 +6207,7 @@ const struct Item gItems[] = [ITEM_BLACK_BELT] = { .name = _("Black Belt"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_FIGHTING_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6199,7 +6222,7 @@ const struct Item gItems[] = [ITEM_POISON_BARB] = { .name = _("Poison Barb"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_POISON_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6214,7 +6237,7 @@ const struct Item gItems[] = [ITEM_SOFT_SAND] = { .name = _("Soft Sand"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_GROUND_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6229,7 +6252,7 @@ const struct Item gItems[] = [ITEM_SHARP_BEAK] = { .name = _("Sharp Beak"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_FLYING_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6244,7 +6267,7 @@ const struct Item gItems[] = [ITEM_TWISTED_SPOON] = { .name = _("Twisted Spoon"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_PSYCHIC_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = sOddIncenseDesc, @@ -6257,7 +6280,7 @@ const struct Item gItems[] = [ITEM_SILVER_POWDER] = { .name = _("Silver Powder"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_BUG_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6272,7 +6295,7 @@ const struct Item gItems[] = [ITEM_HARD_STONE] = { .name = _("Hard Stone"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_ROCK_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = sRockIncenseDesc, @@ -6285,7 +6308,7 @@ const struct Item gItems[] = [ITEM_SPELL_TAG] = { .name = _("Spell Tag"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_GHOST_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6300,7 +6323,7 @@ const struct Item gItems[] = [ITEM_DRAGON_FANG] = { .name = _("Dragon Fang"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_DRAGON_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6315,7 +6338,7 @@ const struct Item gItems[] = [ITEM_BLACK_GLASSES] = { .name = _("Black Glasses"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 1000 : 100), .holdEffect = HOLD_EFFECT_DARK_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6330,7 +6353,7 @@ const struct Item gItems[] = [ITEM_METAL_COAT] = { .name = _("Metal Coat"), - .price = 2000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 2000 : 100), .holdEffect = HOLD_EFFECT_STEEL_POWER, .holdEffectParam = TYPE_BOOST_PARAM, .description = COMPOUND_STRING("A hold item that\n" @@ -6347,11 +6370,11 @@ const struct Item gItems[] = [ITEM_CHOICE_BAND] = { .name = _("Choice Band"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 100000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_CHOICE_BAND, - .description = COMPOUND_STRING("Raises a move's\n" - "power, but permits\n" - "only that move."), + .description = COMPOUND_STRING("Boosts Attack, but\n" + "allows the use of\n" + "only one move."), .pocket = POCKET_ITEMS, .type = ITEM_USE_BAG_MENU, .fieldUseFunc = ItemUseOutOfBattle_CannotUse, @@ -6361,7 +6384,7 @@ const struct Item gItems[] = [ITEM_CHOICE_SPECS] = { .name = _("Choice Specs"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 100000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_CHOICE_SPECS, .description = COMPOUND_STRING("Boosts Sp. Atk, but\n" "allows the use of\n" @@ -6375,7 +6398,7 @@ const struct Item gItems[] = [ITEM_CHOICE_SCARF] = { .name = _("Choice Scarf"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 100000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_CHOICE_SCARF, .description = COMPOUND_STRING("Boosts Speed, but\n" "allows the use of\n" @@ -6391,7 +6414,7 @@ const struct Item gItems[] = [ITEM_FLAME_ORB] = { .name = _("Flame Orb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_FLAME_ORB, .description = COMPOUND_STRING("A bizarre orb that\n" "inflicts a burn on\n" @@ -6405,7 +6428,7 @@ const struct Item gItems[] = [ITEM_TOXIC_ORB] = { .name = _("Toxic Orb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_TOXIC_ORB, .description = COMPOUND_STRING("A bizarre orb that\n" "badly poisons the\n" @@ -6421,7 +6444,7 @@ const struct Item gItems[] = [ITEM_DAMP_ROCK] = { .name = _("Damp Rock"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_DAMP_ROCK, .description = COMPOUND_STRING("Extends the length\n" "of Rain Dance if\n" @@ -6435,7 +6458,7 @@ const struct Item gItems[] = [ITEM_HEAT_ROCK] = { .name = _("Heat Rock"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_HEAT_ROCK, .description = COMPOUND_STRING("Extends the length\n" "of Sunny Day if\n" @@ -6449,7 +6472,7 @@ const struct Item gItems[] = [ITEM_SMOOTH_ROCK] = { .name = _("Smooth Rock"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_SMOOTH_ROCK, .description = COMPOUND_STRING("Extends the length\n" "of Sandstorm if\n" @@ -6463,7 +6486,7 @@ const struct Item gItems[] = [ITEM_ICY_ROCK] = { .name = _("Icy Rock"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_ICY_ROCK, .description = COMPOUND_STRING("Extends the length\n" "of the move Hail\n" @@ -6479,7 +6502,7 @@ const struct Item gItems[] = [ITEM_ELECTRIC_SEED] = { .name = _("Electric Seed"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_SEEDS, .holdEffectParam = HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN, .description = COMPOUND_STRING("Boosts Defense on\n" @@ -6494,7 +6517,7 @@ const struct Item gItems[] = [ITEM_PSYCHIC_SEED] = { .name = _("Psychic Seed"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_SEEDS, .holdEffectParam = HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN, .description = COMPOUND_STRING("Boosts Sp. Def. on\n" @@ -6509,7 +6532,7 @@ const struct Item gItems[] = [ITEM_MISTY_SEED] = { .name = _("Misty Seed"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_SEEDS, .holdEffectParam = HOLD_EFFECT_PARAM_MISTY_TERRAIN, .description = COMPOUND_STRING("Boosts Sp. Def. on\n" @@ -6524,7 +6547,7 @@ const struct Item gItems[] = [ITEM_GRASSY_SEED] = { .name = _("Grassy Seed"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_SEEDS, .holdEffectParam = HOLD_EFFECT_PARAM_GRASSY_TERRAIN, .description = COMPOUND_STRING("Boosts Defense on\n" @@ -6541,7 +6564,7 @@ const struct Item gItems[] = [ITEM_ABSORB_BULB] = { .name = _("Absorb Bulb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_ABSORB_BULB, .holdEffectParam = 0, .description = COMPOUND_STRING("Raises Sp. Atk if\n" @@ -6556,7 +6579,7 @@ const struct Item gItems[] = [ITEM_CELL_BATTERY] = { .name = _("Cell Battery"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_CELL_BATTERY, .holdEffectParam = 0, .description = COMPOUND_STRING("Raises Atk if the\n" @@ -6571,7 +6594,7 @@ const struct Item gItems[] = [ITEM_LUMINOUS_MOSS] = { .name = _("Luminous Moss"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_7) ? 4000 : 1000), .holdEffect = HOLD_EFFECT_LUMINOUS_MOSS, .holdEffectParam = 0, .description = COMPOUND_STRING("Raises Sp. Def if\n" @@ -6586,7 +6609,7 @@ const struct Item gItems[] = [ITEM_SNOWBALL] = { .name = _("Snowball"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_SNOWBALL, .holdEffectParam = 0, .description = COMPOUND_STRING("Raises Atk if its\n" @@ -6603,7 +6626,7 @@ const struct Item gItems[] = [ITEM_BRIGHT_POWDER] = { .name = _("Bright Powder"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : ((I_PRICE >= GEN_7) ? 4000 : 10), .holdEffect = HOLD_EFFECT_EVASION_UP, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -6618,7 +6641,7 @@ const struct Item gItems[] = [ITEM_WHITE_HERB] = { .name = _("White Herb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_RESTORE_STATS, .description = COMPOUND_STRING("A hold item that\n" "restores any\n" @@ -6632,13 +6655,14 @@ const struct Item gItems[] = [ITEM_EXP_SHARE] = { .name = _("Exp. Share"), - .price = 3000, .holdEffect = HOLD_EFFECT_EXP_SHARE, #if I_EXP_SHARE_ITEM >= GEN_6 + .price = 0, .description = COMPOUND_STRING("This device gives\n" "exp. to other\n" "party members."), #else + .price = 3000, .description = COMPOUND_STRING("A hold item that\n" "gets Exp. points\n" "from battles."), @@ -6652,7 +6676,7 @@ const struct Item gItems[] = [ITEM_QUICK_CLAW] = { .name = _("Quick Claw"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_QUICK_CLAW, .holdEffectParam = 20, .description = COMPOUND_STRING("A hold item that\n" @@ -6667,7 +6691,7 @@ const struct Item gItems[] = [ITEM_SOOTHE_BELL] = { .name = _("Soothe Bell"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_FRIENDSHIP_UP, .description = COMPOUND_STRING("A hold item that\n" "calms spirits and\n" @@ -6681,7 +6705,7 @@ const struct Item gItems[] = [ITEM_MENTAL_HERB] = { .name = _("Mental Herb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_MENTAL_HERB, #if B_MENTAL_HERB >= GEN_5 .description = COMPOUND_STRING("Snaps Pokémon out\n" @@ -6701,7 +6725,7 @@ const struct Item gItems[] = [ITEM_KINGS_ROCK] = { .name = _("King's Rock"), - .price = 5000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 5000 : 100), .holdEffect = HOLD_EFFECT_FLINCH, .holdEffectParam = 10, .description = sKingsRockDesc, @@ -6714,7 +6738,7 @@ const struct Item gItems[] = [ITEM_AMULET_COIN] = { .name = _("Amulet Coin"), - .price = 10000, + .price = (I_PRICE >= GEN_9) ? 30000 : ((I_PRICE >= GEN_7) ? 10000 : 100), .holdEffect = HOLD_EFFECT_DOUBLE_PRIZE, .description = sLuckIncenseDesc, .pocket = POCKET_ITEMS, @@ -6726,7 +6750,7 @@ const struct Item gItems[] = [ITEM_CLEANSE_TAG] = { .name = _("Cleanse Tag"), - .price = 5000, + .price = (I_PRICE >= GEN_7) ? 5000 : 200, .holdEffect = HOLD_EFFECT_REPEL, .description = sPureIncenseDesc, .pocket = POCKET_ITEMS, @@ -6738,7 +6762,7 @@ const struct Item gItems[] = [ITEM_SMOKE_BALL] = { .name = _("Smoke Ball"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_CAN_ALWAYS_RUN, .description = COMPOUND_STRING("A hold item that\n" "assures fleeing\n" @@ -6752,7 +6776,7 @@ const struct Item gItems[] = [ITEM_FOCUS_BAND] = { .name = _("Focus Band"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_FOCUS_BAND, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -6767,7 +6791,7 @@ const struct Item gItems[] = [ITEM_LUCKY_EGG] = { .name = _("Lucky Egg"), - .price = 10000, + .price = (I_PRICE >= GEN_7) ? 10000 : 200, .holdEffect = HOLD_EFFECT_LUCKY_EGG, .description = COMPOUND_STRING("A hold item that\n" "boosts Exp. points\n" @@ -6781,7 +6805,7 @@ const struct Item gItems[] = [ITEM_SCOPE_LENS] = { .name = _("Scope Lens"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_SCOPE_LENS, .description = COMPOUND_STRING("A hold item that\n" "improves the\n" @@ -6795,7 +6819,7 @@ const struct Item gItems[] = [ITEM_LEFTOVERS] = { .name = _("Leftovers"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_LEFTOVERS, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -6810,7 +6834,7 @@ const struct Item gItems[] = [ITEM_SHELL_BELL] = { .name = _("Shell Bell"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_SHELL_BELL, .holdEffectParam = 8, .description = COMPOUND_STRING("A hold item that\n" @@ -6825,7 +6849,7 @@ const struct Item gItems[] = [ITEM_WIDE_LENS] = { .name = _("Wide Lens"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_WIDE_LENS, .holdEffectParam = 10, .description = COMPOUND_STRING("A magnifying lens\n" @@ -6840,7 +6864,7 @@ const struct Item gItems[] = [ITEM_MUSCLE_BAND] = { .name = _("Muscle Band"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_MUSCLE_BAND, .holdEffectParam = 10, .description = COMPOUND_STRING("A headband that\n" @@ -6855,7 +6879,7 @@ const struct Item gItems[] = [ITEM_WISE_GLASSES] = { .name = _("Wise Glasses"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 8000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_WISE_GLASSES, .holdEffectParam = 10, .description = COMPOUND_STRING("A pair of glasses\n" @@ -6870,7 +6894,7 @@ const struct Item gItems[] = [ITEM_EXPERT_BELT] = { .name = _("Expert Belt"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_EXPERT_BELT, .holdEffectParam = 20, .description = COMPOUND_STRING("A belt that boosts\n" @@ -6885,7 +6909,7 @@ const struct Item gItems[] = [ITEM_LIGHT_CLAY] = { .name = _("Light Clay"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_LIGHT_CLAY, .description = COMPOUND_STRING("Extends the length\n" "of barrier moves\n" @@ -6899,7 +6923,7 @@ const struct Item gItems[] = [ITEM_LIFE_ORB] = { .name = _("Life Orb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 50000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_LIFE_ORB, .description = COMPOUND_STRING("Boosts the power of\n" "moves at the cost\n" @@ -6913,7 +6937,7 @@ const struct Item gItems[] = [ITEM_POWER_HERB] = { .name = _("Power Herb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_POWER_HERB, .description = COMPOUND_STRING("Allows immediate\n" "use of a move that\n" @@ -6927,7 +6951,7 @@ const struct Item gItems[] = [ITEM_FOCUS_SASH] = { .name = _("Focus Sash"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 50000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_FOCUS_SASH, .description = COMPOUND_STRING("If the holder has\n" "full HP, it endures\n" @@ -6941,7 +6965,7 @@ const struct Item gItems[] = [ITEM_ZOOM_LENS] = { .name = _("Zoom Lens"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_ZOOM_LENS, .holdEffectParam = 20, .description = COMPOUND_STRING("If the holder moves\n" @@ -6956,7 +6980,7 @@ const struct Item gItems[] = [ITEM_METRONOME] = { .name = _("Metronome"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_METRONOME, .holdEffectParam = 20, .description = COMPOUND_STRING("A held item that\n" @@ -6971,7 +6995,7 @@ const struct Item gItems[] = [ITEM_IRON_BALL] = { .name = _("Iron Ball"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_IRON_BALL, .description = COMPOUND_STRING("Cuts Speed and lets\n" "Flying-types be hit\n" @@ -6985,7 +7009,7 @@ const struct Item gItems[] = [ITEM_LAGGING_TAIL] = { .name = _("Lagging Tail"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_LAGGING_TAIL, .description = sFullIncenseDesc, .pocket = POCKET_ITEMS, @@ -6997,7 +7021,7 @@ const struct Item gItems[] = [ITEM_DESTINY_KNOT] = { .name = _("Destiny Knot"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_DESTINY_KNOT, .description = COMPOUND_STRING("If the holder falls\n" "in love, the foe\n" @@ -7011,7 +7035,7 @@ const struct Item gItems[] = [ITEM_BLACK_SLUDGE] = { .name = _("Black Sludge"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_BLACK_SLUDGE, .description = COMPOUND_STRING("Gradually restores\n" "HP of Poison-types.\n" @@ -7025,7 +7049,7 @@ const struct Item gItems[] = [ITEM_GRIP_CLAW] = { .name = _("Grip Claw"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_GRIP_CLAW, .description = COMPOUND_STRING("Makes binding moves\n" "used by the holder\n" @@ -7039,7 +7063,7 @@ const struct Item gItems[] = [ITEM_STICKY_BARB] = { .name = _("Sticky Barb"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_STICKY_BARB, .description = COMPOUND_STRING("Damages the holder\n" "each turn. May latch\n" @@ -7053,7 +7077,7 @@ const struct Item gItems[] = [ITEM_SHED_SHELL] = { .name = _("Shed Shell"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 100), .holdEffect = HOLD_EFFECT_SHED_SHELL, .description = COMPOUND_STRING("Enables the holder\n" "to switch out of\n" @@ -7067,7 +7091,7 @@ const struct Item gItems[] = [ITEM_BIG_ROOT] = { .name = _("Big Root"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_BIG_ROOT, .holdEffectParam = 30, .description = COMPOUND_STRING("A held item that\n" @@ -7082,7 +7106,7 @@ const struct Item gItems[] = [ITEM_RAZOR_CLAW] = { .name = _("Razor Claw"), - .price = 5000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 5000 : 2100), .holdEffect = HOLD_EFFECT_SCOPE_LENS, .description = COMPOUND_STRING("A hooked claw that\n" "ups the holder's\n" @@ -7096,7 +7120,7 @@ const struct Item gItems[] = [ITEM_RAZOR_FANG] = { .name = _("Razor Fang"), - .price = 5000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 5000 : 2100), .holdEffect = HOLD_EFFECT_FLINCH, .holdEffectParam = 10, .description = sKingsRockDesc, @@ -7109,7 +7133,7 @@ const struct Item gItems[] = [ITEM_EVIOLITE] = { .name = _("Eviolite"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 50000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_EVIOLITE, .holdEffectParam = 50, .description = COMPOUND_STRING("Raises the Def and\n" @@ -7124,7 +7148,7 @@ const struct Item gItems[] = [ITEM_FLOAT_STONE] = { .name = _("Float Stone"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_FLOAT_STONE, .description = COMPOUND_STRING("It's so light that\n" "when held, it halves\n" @@ -7138,7 +7162,7 @@ const struct Item gItems[] = [ITEM_ROCKY_HELMET] = { .name = _("Rocky Helmet"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 50000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_ROCKY_HELMET, .holdEffectParam = 0, .description = COMPOUND_STRING("Hurts the foe if\n" @@ -7153,7 +7177,7 @@ const struct Item gItems[] = [ITEM_AIR_BALLOON] = { .name = _("Air Balloon"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_AIR_BALLOON, .holdEffectParam = 0, .description = COMPOUND_STRING("Elevates the holder\n" @@ -7168,7 +7192,7 @@ const struct Item gItems[] = [ITEM_RED_CARD] = { .name = _("Red Card"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 3000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_RED_CARD, .holdEffectParam = 0, .description = COMPOUND_STRING("Switches out the\n" @@ -7183,7 +7207,7 @@ const struct Item gItems[] = [ITEM_RING_TARGET] = { .name = _("Ring Target"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 10000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_RING_TARGET, .holdEffectParam = 0, .description = COMPOUND_STRING("Moves that wouldn't\n" @@ -7198,7 +7222,7 @@ const struct Item gItems[] = [ITEM_BINDING_BAND] = { .name = _("Binding Band"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_BINDING_BAND, .description = COMPOUND_STRING("Increases the\n" "power of binding\n" @@ -7212,7 +7236,7 @@ const struct Item gItems[] = [ITEM_EJECT_BUTTON] = { .name = _("Eject Button"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : ((I_PRICE >= GEN_7) ? 4000 : 200), .holdEffect = HOLD_EFFECT_EJECT_BUTTON, .holdEffectParam = 0, .description = COMPOUND_STRING("Switches out the\n" @@ -7227,7 +7251,7 @@ const struct Item gItems[] = [ITEM_WEAKNESS_POLICY] = { .name = _("WeaknssPolicy"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 50000 : 1000, .holdEffect = HOLD_EFFECT_WEAKNESS_POLICY, .holdEffectParam = 0, .description = COMPOUND_STRING("If hit by a Super\n" @@ -7242,7 +7266,7 @@ const struct Item gItems[] = [ITEM_ASSAULT_VEST] = { .name = _("Assault Vest"), - .price = 1000, + .price = (I_PRICE >= GEN_9) ? 50000 : 1000, .holdEffect = HOLD_EFFECT_ASSAULT_VEST, .holdEffectParam = 50, .description = COMPOUND_STRING("Raises Sp. Def but\n" @@ -7257,7 +7281,7 @@ const struct Item gItems[] = [ITEM_SAFETY_GOGGLES] = { .name = _("SafetyGoggles"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : ((I_PRICE >= GEN_7) ? 4000 : 1000), .holdEffect = HOLD_EFFECT_SAFETY_GOGGLES, .description = COMPOUND_STRING("Protect from\n" "weather damage and\n" @@ -7271,7 +7295,7 @@ const struct Item gItems[] = [ITEM_ADRENALINE_ORB] = { .name = _("AdrenalineOrb"), - .price = 300, + .price = (I_PRICE >= GEN_9) ? 5000 : ((I_PRICE >= GEN_8) ? 4000 : 300), .holdEffect = HOLD_EFFECT_ADRENALINE_ORB, .description = COMPOUND_STRING("Boosts Speed if the\n" "user is intimidated,\n" @@ -7285,7 +7309,7 @@ const struct Item gItems[] = [ITEM_TERRAIN_EXTENDER] = { .name = _("TerainExtendr"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : 4000, .holdEffect = HOLD_EFFECT_TERRAIN_EXTENDER, .description = COMPOUND_STRING("Extends the length\n" "of the active\n" @@ -7299,7 +7323,7 @@ const struct Item gItems[] = [ITEM_PROTECTIVE_PADS] = { .name = _("ProtectvePads"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : 4000, .holdEffect = HOLD_EFFECT_PROTECTIVE_PADS, .description = COMPOUND_STRING("Guard the holder\n" "from contact move\n" @@ -7313,7 +7337,7 @@ const struct Item gItems[] = [ITEM_THROAT_SPRAY] = { .name = _("Throat Spray"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_THROAT_SPRAY, .description = COMPOUND_STRING("Raises Sp. Atk. if\n" "the holder uses a\n" @@ -7327,7 +7351,7 @@ const struct Item gItems[] = [ITEM_EJECT_PACK] = { .name = _("Eject Pack"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : 4000, .holdEffect = HOLD_EFFECT_EJECT_PACK, .description = COMPOUND_STRING("Forces the user to\n" "switch if its stats\n" @@ -7341,7 +7365,7 @@ const struct Item gItems[] = [ITEM_HEAVY_DUTY_BOOTS] = { .name = _("Heavy-DtyBts"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_HEAVY_DUTY_BOOTS, .description = COMPOUND_STRING("Boots that prevent\n" "effects of traps\n" @@ -7355,7 +7379,7 @@ const struct Item gItems[] = [ITEM_BLUNDER_POLICY] = { .name = _("BlundrPolicy"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 30000 : 4000, .holdEffect = HOLD_EFFECT_BLUNDER_POLICY, .description = COMPOUND_STRING("Raises Speed if\n" "the user misses\n" @@ -7369,7 +7393,7 @@ const struct Item gItems[] = [ITEM_ROOM_SERVICE] = { .name = _("Room Service"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 20000 : 4000, .holdEffect = HOLD_EFFECT_ROOM_SERVICE, .description = COMPOUND_STRING("Lowers Speed if\n" "Trick Room is\n" @@ -7383,7 +7407,7 @@ const struct Item gItems[] = [ITEM_UTILITY_UMBRELLA] = { .name = _("UtltyUmbrlla"), - .price = 4000, + .price = (I_PRICE >= GEN_9) ? 15000 : 4000, .holdEffect = HOLD_EFFECT_UTILITY_UMBRELLA, .description = COMPOUND_STRING("An umbrella that\n" "protects from\n" @@ -7399,7 +7423,7 @@ const struct Item gItems[] = [ITEM_CHERI_BERRY] = { .name = _("Cheri Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_PAR, .description = COMPOUND_STRING("A hold item that\n" "heals paralysis\n" @@ -7414,7 +7438,7 @@ const struct Item gItems[] = [ITEM_CHESTO_BERRY] = { .name = _("Chesto Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_SLP, .description = COMPOUND_STRING("A hold item that\n" "awakens Pokémon\n" @@ -7429,7 +7453,7 @@ const struct Item gItems[] = [ITEM_PECHA_BERRY] = { .name = _("Pecha Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_PSN, .description = COMPOUND_STRING("A hold item that\n" "heals poisoning\n" @@ -7444,7 +7468,7 @@ const struct Item gItems[] = [ITEM_RAWST_BERRY] = { .name = _("Rawst Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_BRN, .description = COMPOUND_STRING("A hold item that\n" "heals a burn in\n" @@ -7459,7 +7483,7 @@ const struct Item gItems[] = [ITEM_ASPEAR_BERRY] = { .name = _("Aspear Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_FRZ, .description = COMPOUND_STRING("A hold item that\n" "defrosts Pokémon\n" @@ -7474,7 +7498,7 @@ const struct Item gItems[] = [ITEM_LEPPA_BERRY] = { .name = _("Leppa Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESTORE_PP, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -7490,7 +7514,7 @@ const struct Item gItems[] = [ITEM_ORAN_BERRY] = { .name = _("Oran Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESTORE_HP, .holdEffectParam = 10, .description = COMPOUND_STRING("A hold item that\n" @@ -7506,7 +7530,7 @@ const struct Item gItems[] = [ITEM_PERSIM_BERRY] = { .name = _("Persim Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_CONFUSION, .description = COMPOUND_STRING("A hold item that\n" "heals confusion\n" @@ -7521,7 +7545,7 @@ const struct Item gItems[] = [ITEM_LUM_BERRY] = { .name = _("Lum Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CURE_STATUS, .description = COMPOUND_STRING("A hold item that\n" "heals any status\n" @@ -7536,7 +7560,7 @@ const struct Item gItems[] = [ITEM_SITRUS_BERRY] = { .name = _("Sitrus Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, #if I_SITRUS_BERRY_HEAL >= GEN_4 .holdEffect = HOLD_EFFECT_RESTORE_PCT_HP, .holdEffectParam = 25, @@ -7560,7 +7584,7 @@ const struct Item gItems[] = [ITEM_FIGY_BERRY] = { .name = _("Figy Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CONFUSE_SPICY, .holdEffectParam = CONFUSE_BERRY_HEAL_FRACTION, .description = sFigyBerryDesc, @@ -7573,7 +7597,7 @@ const struct Item gItems[] = [ITEM_WIKI_BERRY] = { .name = _("Wiki Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CONFUSE_DRY, .holdEffectParam = CONFUSE_BERRY_HEAL_FRACTION, .description = sFigyBerryDesc, @@ -7586,7 +7610,7 @@ const struct Item gItems[] = [ITEM_MAGO_BERRY] = { .name = _("Mago Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CONFUSE_SWEET, .holdEffectParam = CONFUSE_BERRY_HEAL_FRACTION, .description = sFigyBerryDesc, @@ -7599,7 +7623,7 @@ const struct Item gItems[] = [ITEM_AGUAV_BERRY] = { .name = _("Aguav Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CONFUSE_BITTER, .holdEffectParam = CONFUSE_BERRY_HEAL_FRACTION, .description = sFigyBerryDesc, @@ -7612,7 +7636,7 @@ const struct Item gItems[] = [ITEM_IAPAPA_BERRY] = { .name = _("Iapapa Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CONFUSE_SOUR, .holdEffectParam = CONFUSE_BERRY_HEAL_FRACTION, .description = sFigyBerryDesc, @@ -7625,7 +7649,7 @@ const struct Item gItems[] = [ITEM_RAZZ_BERRY] = { .name = _("Razz Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Razz."), @@ -7638,7 +7662,7 @@ const struct Item gItems[] = [ITEM_BLUK_BERRY] = { .name = _("Bluk Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Bluk."), @@ -7651,7 +7675,7 @@ const struct Item gItems[] = [ITEM_NANAB_BERRY] = { .name = _("Nanab Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Nanab."), @@ -7664,7 +7688,7 @@ const struct Item gItems[] = [ITEM_WEPEAR_BERRY] = { .name = _("Wepear Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Wepear."), @@ -7677,7 +7701,7 @@ const struct Item gItems[] = [ITEM_PINAP_BERRY] = { .name = _("Pinap Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Pinap."), @@ -7690,7 +7714,7 @@ const struct Item gItems[] = [ITEM_POMEG_BERRY] = { .name = _("Pomeg Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base HP."), @@ -7703,7 +7727,7 @@ const struct Item gItems[] = [ITEM_KELPSY_BERRY] = { .name = _("Kelpsy Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base Attack."), @@ -7716,7 +7740,7 @@ const struct Item gItems[] = [ITEM_QUALOT_BERRY] = { .name = _("Qualot Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base Defense."), @@ -7729,7 +7753,7 @@ const struct Item gItems[] = [ITEM_HONDEW_BERRY] = { .name = _("Hondew Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base Sp. Atk."), @@ -7742,7 +7766,7 @@ const struct Item gItems[] = [ITEM_GREPA_BERRY] = { .name = _("Grepa Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base Sp. Def."), @@ -7755,7 +7779,7 @@ const struct Item gItems[] = [ITEM_TAMATO_BERRY] = { .name = _("Tamato Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("Makes a Pokémon\n" "friendly but lowers\n" "base Speed."), @@ -7768,7 +7792,7 @@ const struct Item gItems[] = [ITEM_CORNN_BERRY] = { .name = _("Cornn Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Cornn."), @@ -7781,7 +7805,7 @@ const struct Item gItems[] = [ITEM_MAGOST_BERRY] = { .name = _("Magost Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Magost."), @@ -7794,7 +7818,7 @@ const struct Item gItems[] = [ITEM_RABUTA_BERRY] = { .name = _("Rabuta Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Rabuta."), @@ -7807,7 +7831,7 @@ const struct Item gItems[] = [ITEM_NOMEL_BERRY] = { .name = _("Nomel Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Nomel."), @@ -7820,7 +7844,7 @@ const struct Item gItems[] = [ITEM_SPELON_BERRY] = { .name = _("Spelon Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Spelon."), @@ -7833,7 +7857,7 @@ const struct Item gItems[] = [ITEM_PAMTRE_BERRY] = { .name = _("Pamtre Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Pamtre."), @@ -7846,7 +7870,7 @@ const struct Item gItems[] = [ITEM_WATMEL_BERRY] = { .name = _("Watmel Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Watmel."), @@ -7859,7 +7883,7 @@ const struct Item gItems[] = [ITEM_DURIN_BERRY] = { .name = _("Durin Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Durin."), @@ -7872,7 +7896,7 @@ const struct Item gItems[] = [ITEM_BELUE_BERRY] = { .name = _("Belue Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow Belue."), @@ -7885,7 +7909,7 @@ const struct Item gItems[] = [ITEM_CHILAN_BERRY] = { .name = _("Chilan Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_NORMAL, .description = COMPOUND_STRING("A hold item that\n" @@ -7900,7 +7924,7 @@ const struct Item gItems[] = [ITEM_OCCA_BERRY] = { .name = _("Occa Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_FIRE, .description = COMPOUND_STRING("A hold item that\n" @@ -7915,7 +7939,7 @@ const struct Item gItems[] = [ITEM_PASSHO_BERRY] = { .name = _("Passho Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_WATER, .description = COMPOUND_STRING("A hold item that\n" @@ -7930,7 +7954,7 @@ const struct Item gItems[] = [ITEM_WACAN_BERRY] = { .name = _("Wacan Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_ELECTRIC, .description = COMPOUND_STRING("A hold item that\n" @@ -7945,7 +7969,7 @@ const struct Item gItems[] = [ITEM_RINDO_BERRY] = { .name = _("Rindo Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_GRASS, .description = COMPOUND_STRING("A hold item that\n" @@ -7960,7 +7984,7 @@ const struct Item gItems[] = [ITEM_YACHE_BERRY] = { .name = _("Yache Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_ICE, .description = COMPOUND_STRING("A hold item that\n" @@ -7975,7 +7999,7 @@ const struct Item gItems[] = [ITEM_CHOPLE_BERRY] = { .name = _("Chople Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_FIGHTING, .description = COMPOUND_STRING("A hold item that\n" @@ -7990,7 +8014,7 @@ const struct Item gItems[] = [ITEM_KEBIA_BERRY] = { .name = _("Kebia Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_POISON, .description = COMPOUND_STRING("A hold item that\n" @@ -8005,7 +8029,7 @@ const struct Item gItems[] = [ITEM_SHUCA_BERRY] = { .name = _("Shuca Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_GROUND, .description = COMPOUND_STRING("A hold item that\n" @@ -8020,7 +8044,7 @@ const struct Item gItems[] = [ITEM_COBA_BERRY] = { .name = _("Coba Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_FLYING, .description = COMPOUND_STRING("A hold item that\n" @@ -8035,7 +8059,7 @@ const struct Item gItems[] = [ITEM_PAYAPA_BERRY] = { .name = _("Payapa Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_PSYCHIC, .description = COMPOUND_STRING("A hold item that\n" @@ -8050,7 +8074,7 @@ const struct Item gItems[] = [ITEM_TANGA_BERRY] = { .name = _("Tanga Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_BUG, .description = COMPOUND_STRING("A hold item that\n" @@ -8065,7 +8089,7 @@ const struct Item gItems[] = [ITEM_CHARTI_BERRY] = { .name = _("Charti Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_ROCK, .description = COMPOUND_STRING("A hold item that\n" @@ -8080,7 +8104,7 @@ const struct Item gItems[] = [ITEM_KASIB_BERRY] = { .name = _("Kasib Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_GHOST, .description = COMPOUND_STRING("A hold item that\n" @@ -8095,7 +8119,7 @@ const struct Item gItems[] = [ITEM_HABAN_BERRY] = { .name = _("Haban Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_DRAGON, .description = COMPOUND_STRING("A hold item that\n" @@ -8110,7 +8134,7 @@ const struct Item gItems[] = [ITEM_COLBUR_BERRY] = { .name = _("Colbur Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_DARK, .description = COMPOUND_STRING("A hold item that\n" @@ -8125,7 +8149,7 @@ const struct Item gItems[] = [ITEM_BABIRI_BERRY] = { .name = _("Babiri Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_STEEL, .description = COMPOUND_STRING("A hold item that\n" @@ -8140,7 +8164,7 @@ const struct Item gItems[] = [ITEM_ROSELI_BERRY] = { .name = _("Roseli Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RESIST_BERRY, .holdEffectParam = TYPE_FAIRY, .description = COMPOUND_STRING("A hold item that\n" @@ -8155,7 +8179,7 @@ const struct Item gItems[] = [ITEM_LIECHI_BERRY] = { .name = _("Liechi Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_ATTACK_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8170,7 +8194,7 @@ const struct Item gItems[] = [ITEM_GANLON_BERRY] = { .name = _("Ganlon Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_DEFENSE_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8185,7 +8209,7 @@ const struct Item gItems[] = [ITEM_SALAC_BERRY] = { .name = _("Salac Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_SPEED_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8200,7 +8224,7 @@ const struct Item gItems[] = [ITEM_PETAYA_BERRY] = { .name = _("Petaya Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_SP_ATTACK_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8215,7 +8239,7 @@ const struct Item gItems[] = [ITEM_APICOT_BERRY] = { .name = _("Apicot Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_SP_DEFENSE_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8230,7 +8254,7 @@ const struct Item gItems[] = [ITEM_LANSAT_BERRY] = { .name = _("Lansat Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CRITICAL_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8245,7 +8269,7 @@ const struct Item gItems[] = [ITEM_STARF_BERRY] = { .name = _("Starf Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_RANDOM_STAT_UP, .holdEffectParam = 4, .description = COMPOUND_STRING("A hold item that\n" @@ -8260,7 +8284,7 @@ const struct Item gItems[] = [ITEM_ENIGMA_BERRY] = { .name = _("Enigma Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_ENIGMA_BERRY, .description = COMPOUND_STRING("A hold item that\n" "heals from super\n" @@ -8274,7 +8298,7 @@ const struct Item gItems[] = [ITEM_MICLE_BERRY] = { .name = _("Micle Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_MICLE_BERRY, .holdEffectParam = 4, .description = COMPOUND_STRING("When held, it ups\n" @@ -8289,7 +8313,7 @@ const struct Item gItems[] = [ITEM_CUSTAP_BERRY] = { .name = _("Custap Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_CUSTAP_BERRY, .holdEffectParam = 4, .description = COMPOUND_STRING("It allows a Pokémon\n" @@ -8304,7 +8328,7 @@ const struct Item gItems[] = [ITEM_JABOCA_BERRY] = { .name = _("Jaboca Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_JABOCA_BERRY, .description = COMPOUND_STRING("If hit by a physical\n" "move, it will hurt\n" @@ -8318,7 +8342,7 @@ const struct Item gItems[] = [ITEM_ROWAP_BERRY] = { .name = _("Rowap Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_ROWAP_BERRY, .description = COMPOUND_STRING("If hit by a special\n" "move, it will hurt\n" @@ -8332,7 +8356,7 @@ const struct Item gItems[] = [ITEM_KEE_BERRY] = { .name = _("Kee Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_KEE_BERRY, .description = COMPOUND_STRING("If hit by a physical\n" "move, it raises the\n" @@ -8346,7 +8370,7 @@ const struct Item gItems[] = [ITEM_MARANGA_BERRY] = { .name = _("Maranga Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .holdEffect = HOLD_EFFECT_MARANGA_BERRY, .description = COMPOUND_STRING("If hit by a special\n" "move, it raises the\n" @@ -8360,7 +8384,7 @@ const struct Item gItems[] = [ITEM_ENIGMA_BERRY_E_READER] = { .name = _("Enigma Berry"), - .price = 20, + .price = (I_BERRY_PRICE >= GEN_8) ? 80 : 20, .description = COMPOUND_STRING("{POKEBLOCK} ingredient.\n" "Plant in loamy soil\n" "to grow a mystery."), @@ -10162,8 +10186,8 @@ const struct Item gItems[] = "Storage System."), .importance = 1, .pocket = POCKET_KEY_ITEMS, - .type = ITEM_USE_BAG_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .type = ITEM_USE_FIELD, + .fieldUseFunc = ItemUseOutOfBattle_PokemonBoxLink, }, [ITEM_COIN_CASE] = @@ -10693,6 +10717,8 @@ const struct Item gItems[] = .flingPower = 30, }, +// GEN 9 ITEMS + [ITEM_CLEAR_AMULET] = { .name = _("Clear Amulet"), @@ -11222,42 +11248,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] = @@ -11351,4 +11371,26 @@ const struct Item gItems[] = .type = ITEM_USE_BAG_MENU, .fieldUseFunc = ItemUseOutOfBattle_CannotUse, }, + + [ITEM_METAL_ALLOY] = + { + .name = _("Metal Alloy"), + .price = 6000, + .description = COMPOUND_STRING("A peculiar metal\n" + "that makes certain\n" + "Pokémon evolve."), + .pocket = POCKET_ITEMS, + .type = ITEM_USE_PARTY_MENU, + .fieldUseFunc = ItemUseOutOfBattle_EvolutionStone, + }, + + [ITEM_STELLAR_TERA_SHARD] = + { + .name = _("StllrTeraShrd"), + .price = 0, + .description = sTeraShardDesc, + .pocket = POCKET_ITEMS, + .type = ITEM_USE_BAG_MENU, + .fieldUseFunc = ItemUseOutOfBattle_CannotUse, + }, }; 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/item_effects.h b/src/data/pokemon/item_effects.h index 2c7401059ed7..e129d9505a7f 100644 --- a/src/data/pokemon/item_effects.h +++ b/src/data/pokemon/item_effects.h @@ -626,6 +626,9 @@ 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, // Berries [ITEM_CHERI_BERRY] = gItemEffect_CheriBerry, diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h index 92c8c7729c85..75cb52732cfd 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[] = diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h deleted file mode 100644 index dc1ad9d4e516..000000000000 --- a/src/data/text/abilities.h +++ /dev/null @@ -1,1234 +0,0 @@ -static const u8 sNoneDescription[] = _("No special ability."); -static const u8 sStenchDescription[] = _("May cause a foe to flinch."); -static const u8 sDrizzleDescription[] = _("Summons rain in battle."); -static const u8 sSpeedBoostDescription[] = _("Gradually boosts Speed."); -static const u8 sBattleArmorDescription[] = _("Blocks critical hits."); -static const u8 sSturdyDescription[] = _("Negates 1-hit KO attacks."); -static const u8 sDampDescription[] = _("Prevents self-destruction."); -static const u8 sLimberDescription[] = _("Prevents paralysis."); -static const u8 sSandVeilDescription[] = _("Ups evasion in a sandstorm."); -static const u8 sStaticDescription[] = _("Paralyzes on contact."); -static const u8 sVoltAbsorbDescription[] = _("Turns electricity into HP."); -static const u8 sWaterAbsorbDescription[] = _("Changes water into HP."); -static const u8 sObliviousDescription[] = _("Prevents attraction."); -static const u8 sCloudNineDescription[] = _("Negates weather effects."); -static const u8 sCompoundEyesDescription[] = _("Raises accuracy."); -static const u8 sInsomniaDescription[] = _("Prevents sleep."); -static const u8 sColorChangeDescription[] = _("Changes type to foe's move."); -static const u8 sImmunityDescription[] = _("Prevents poisoning."); -static const u8 sFlashFireDescription[] = _("Powers up if hit by fire."); -static const u8 sShieldDustDescription[] = _("Prevents added effects."); -static const u8 sOwnTempoDescription[] = _("Prevents confusion."); -static const u8 sSuctionCupsDescription[] = _("Firmly anchors the body."); -static const u8 sIntimidateDescription[] = _("Lowers the foe's Attack."); -static const u8 sShadowTagDescription[] = _("Prevents the foe's escape."); -static const u8 sRoughSkinDescription[] = _("Hurts to touch."); -static const u8 sWonderGuardDescription[] = _("“Supereffective” hits."); -static const u8 sLevitateDescription[] = _("Not hit by Ground attacks."); -static const u8 sEffectSporeDescription[] = _("Leaves spores on contact."); -static const u8 sSynchronizeDescription[] = _("Passes on status problems."); -static const u8 sClearBodyDescription[] = _("Prevents ability reduction."); -static const u8 sNaturalCureDescription[] = _("Heals upon switching out."); -static const u8 sLightningRodDescription[] = _("Draws electrical moves."); -static const u8 sSereneGraceDescription[] = _("Promotes added effects."); -static const u8 sSwiftSwimDescription[] = _("Raises Speed in rain."); -static const u8 sChlorophyllDescription[] = _("Raises Speed in sunshine."); -static const u8 sIlluminateDescription[] = _("Encounter rate increases."); -static const u8 sTraceDescription[] = _("Copies special ability."); -static const u8 sHugePowerDescription[] = _("Raises Attack."); -static const u8 sPoisonPointDescription[] = _("Poisons foe on contact."); -static const u8 sInnerFocusDescription[] = _("Prevents flinching."); -static const u8 sMagmaArmorDescription[] = _("Prevents freezing."); -static const u8 sWaterVeilDescription[] = _("Prevents burns."); -static const u8 sMagnetPullDescription[] = _("Traps Steel-type Pokémon."); -static const u8 sSoundproofDescription[] = _("Avoids sound-based moves."); -static const u8 sRainDishDescription[] = _("Slight HP recovery in rain."); -static const u8 sSandStreamDescription[] = _("Summons a sandstorm."); -static const u8 sPressureDescription[] = _("Raises foe's PP usage."); -static const u8 sThickFatDescription[] = _("Heat-and-cold protection."); -static const u8 sEarlyBirdDescription[] = _("Awakens quickly from sleep."); -static const u8 sFlameBodyDescription[] = _("Burns the foe on contact."); -static const u8 sRunAwayDescription[] = _("Makes escaping easier."); -static const u8 sKeenEyeDescription[] = _("Prevents loss of accuracy."); -static const u8 sHyperCutterDescription[] = _("Prevents Attack reduction."); -static const u8 sPickupDescription[] = _("May pick up items."); -static const u8 sTruantDescription[] = _("Moves only every two turns."); -static const u8 sHustleDescription[] = _("Trades accuracy for power."); -static const u8 sCuteCharmDescription[] = _("Infatuates on contact."); -static const u8 sPlusDescription[] = _("Powers up with Minus."); -static const u8 sMinusDescription[] = _("Powers up with Plus."); -static const u8 sForecastDescription[] = _("Changes with the weather."); -static const u8 sStickyHoldDescription[] = _("Prevents item theft."); -static const u8 sShedSkinDescription[] = _("Heals the body by shedding."); -static const u8 sGutsDescription[] = _("Ups Attack if suffering."); -static const u8 sMarvelScaleDescription[] = _("Ups Defense if suffering."); -static const u8 sLiquidOozeDescription[] = _("Draining causes injury."); -static const u8 sOvergrowDescription[] = _("Ups Grass moves in a pinch."); -static const u8 sBlazeDescription[] = _("Ups Fire moves in a pinch."); -static const u8 sTorrentDescription[] = _("Ups Water moves in a pinch."); -static const u8 sSwarmDescription[] = _("Ups Bug moves in a pinch."); -static const u8 sRockHeadDescription[] = _("Prevents recoil damage."); -static const u8 sDroughtDescription[] = _("Summons sunlight in battle."); -static const u8 sArenaTrapDescription[] = _("Prevents fleeing."); -static const u8 sVitalSpiritDescription[] = _("Prevents sleep."); -static const u8 sWhiteSmokeDescription[] = _("Prevents ability reduction."); -static const u8 sPurePowerDescription[] = _("Raises Attack."); -static const u8 sShellArmorDescription[] = _("Blocks critical hits."); -static const u8 sAirLockDescription[] = _("Negates weather effects."); -static const u8 sTangledFeetDescription[] = _("Ups evasion if confused."); -static const u8 sMotorDriveDescription[] = _("Electricity raises Speed."); -static const u8 sRivalryDescription[] = _("Powers up against rivals."); -static const u8 sSteadfastDescription[] = _("Flinching raises Speed."); -static const u8 sSnowCloakDescription[] = _("Ups evasion in Hail or Snow."); -static const u8 sGluttonyDescription[] = _("Eats Berries early."); -static const u8 sAngerPointDescription[] = _("Critical hits raise Attack."); -static const u8 sUnburdenDescription[] = _("Using a hold item ups Speed."); -static const u8 sHeatproofDescription[] = _("Heat and burn protection."); -static const u8 sSimpleDescription[] = _("Prone to wild stat changes."); -static const u8 sDrySkinDescription[] = _("Prefers moisture to heat."); -static const u8 sDownloadDescription[] = _("Adjusts power favorably."); -static const u8 sIronFistDescription[] = _("Boosts punching moves."); -static const u8 sPoisonHealDescription[] = _("Restores HP if poisoned."); -static const u8 sAdaptabilityDescription[] = _("Boosts same type attacks."); -static const u8 sSkillLinkDescription[] = _("Multi-hit moves hit 5 times."); -static const u8 sHydrationDescription[] = _("Cures status in rain."); -static const u8 sSolarPowerDescription[] = _("Powers up in sunshine."); -static const u8 sQuickFeetDescription[] = _("Ups Speed if suffering."); -static const u8 sNormalizeDescription[] = _("Moves become Normal-type."); -static const u8 sSniperDescription[] = _("Boosts critical hits."); -static const u8 sMagicGuardDescription[] = _("Only damaged by attacks."); -static const u8 sNoGuardDescription[] = _("Ensures that all moves hit."); -static const u8 sStallDescription[] = _("Always moves last."); -static const u8 sTechnicianDescription[] = _("Boosts weaker moves."); -static const u8 sLeafGuardDescription[] = _("Blocks status in sunshine."); -static const u8 sKlutzDescription[] = _("Can't use hold items."); -static const u8 sMoldBreakerDescription[] = _("Moves hit through abilities."); -static const u8 sSuperLuckDescription[] = _("Critical hits land often."); -static const u8 sAftermathDescription[] = _("Fainting damages the foe."); -static const u8 sAnticipationDescription[] = _("Senses dangerous moves."); -static const u8 sForewarnDescription[] = _("Determines a foe's move."); -static const u8 sUnawareDescription[] = _("Ignores stat changes."); -static const u8 sTintedLensDescription[] = _("Ups “not very effective”."); -static const u8 sFilterDescription[] = _("Weakens “supereffective”."); -static const u8 sSlowStartDescription[] = _("Takes a while to get going."); -static const u8 sScrappyDescription[] = _("Hits Ghost-type Pokémon."); -static const u8 sStormDrainDescription[] = _("Draws in Water moves."); -static const u8 sIceBodyDescription[] = _("HP recovery in Hail or Snow."); -#if B_SNOW_WARNING < GEN_9 -static const u8 sSnowWarningDescription[] = _("Summons a Hailstorm."); -#elif B_SNOW_WARNING >= GEN_9 -static const u8 sSnowWarningDescription[] = _("Summons a Snowstorm."); -#endif -static const u8 sHoneyGatherDescription[] = _("May gather Honey."); -static const u8 sFriskDescription[] = _("Checks a foe's item."); -static const u8 sRecklessDescription[] = _("Boosts moves with recoil."); -static const u8 sMultitypeDescription[] = _("Changes type to its Plate."); -static const u8 sFlowerGiftDescription[] = _("Allies power up in sunshine."); -static const u8 sBadDreamsDescription[] = _("Damages sleeping Pokémon."); -static const u8 sPickpocketDescription[] = _("Steals the foe's held item."); -static const u8 sSheerForceDescription[] = _("Trades effects for power."); -static const u8 sContraryDescription[] = _("Inverts stat changes."); -static const u8 sUnnerveDescription[] = _("Foes can't eat Berries."); -static const u8 sDefiantDescription[] = _("Lowered stats up Attack."); -static const u8 sDefeatistDescription[] = _("Gives up at half HP."); -static const u8 sCursedBodyDescription[] = _("Disables moves on contact."); -static const u8 sHealerDescription[] = _("Heals partner Pokémon."); -static const u8 sFriendGuardDescription[] = _("Lowers damage to partner."); -static const u8 sWeakArmorDescription[] = _("Its stats change when hit."); -static const u8 sHeavyMetalDescription[] = _("Doubles weight."); -static const u8 sLightMetalDescription[] = _("Halves weight."); -static const u8 sMultiscaleDescription[] = _("Halves damage at full HP."); -static const u8 sToxicBoostDescription[] = _("Ups Attack if poisoned."); -static const u8 sFlareBoostDescription[] = _("Ups Sp. Atk if burned."); -static const u8 sHarvestDescription[] = _("May recycle a used Berry."); -static const u8 sTelepathyDescription[] = _("Can't be damaged by an ally."); -static const u8 sMoodyDescription[] = _("Stats change gradually."); -static const u8 sOvercoatDescription[] = _("Blocks weather and powder."); -static const u8 sBigPecksDescription[] = _("Prevents Defense loss."); -static const u8 sSandRushDescription[] = _("Ups Speed in a sandstorm."); -static const u8 sWonderSkinDescription[] = _("May avoid status problems."); -static const u8 sAnalyticDescription[] = _("Moving last boosts power."); -static const u8 sIllusionDescription[] = _("Appears as a partner."); -static const u8 sImposterDescription[] = _("Transforms into the foe."); -static const u8 sInfiltratorDescription[] = _("Passes through barriers."); -static const u8 sMummyDescription[] = _("Spreads with contact."); -static const u8 sMoxieDescription[] = _("KOs raise Attack."); -static const u8 sJustifiedDescription[] = _("Dark hits raise Attack."); -static const u8 sRattledDescription[] = _("Raises Speed when scared."); -static const u8 sMagicBounceDescription[] = _("Reflects status moves."); -static const u8 sSapSipperDescription[] = _("Grass increases Attack."); -static const u8 sPranksterDescription[] = _("Status moves go first."); -static const u8 sSandForceDescription[] = _("Powers up in a sandstorm."); -static const u8 sZenModeDescription[] = _("Transforms at half HP."); -static const u8 sVictoryStarDescription[] = _("Raises party accuracy."); -static const u8 sAromaVeilDescription[] = _("Prevents limiting of moves."); -static const u8 sFlowerVeilDescription[] = _("Protects Grass-types."); -static const u8 sCheekPouchDescription[] = _("Eating Berries restores HP."); -static const u8 sProteanDescription[] = _("Changes type to used move."); -static const u8 sFurCoatDescription[] = _("Raises Defense."); -static const u8 sBulletproofDescription[] = _("Avoids some projectiles."); -static const u8 sCompetitiveDescription[] = _("Lowered stats up Sp. Atk."); -static const u8 sStrongJawDescription[] = _("Boosts biting moves."); -static const u8 sRefrigerateDescription[] = _("Normal moves become Ice."); -static const u8 sSweetVeilDescription[] = _("Prevents party from sleep."); -static const u8 sStanceChangeDescription[] = _("Transforms as it battles."); -static const u8 sGaleWingsDescription[] = _("Flying moves go first."); -static const u8 sMegaLauncherDescription[] = _("Boosts pulse moves."); -static const u8 sGrassPeltDescription[] = _("Ups Defense in grass."); -static const u8 sSymbiosisDescription[] = _("Passes its item to an ally."); -static const u8 sToughClawsDescription[] = _("Boosts contact moves."); -static const u8 sPixilateDescription[] = _("Normal moves become Fairy."); -static const u8 sGooeyDescription[] = _("Lowers Speed on contact."); -static const u8 sAerilateDescription[] = _("Normal moves become Flying."); -static const u8 sParentalBondDescription[] = _("Moves hit twice."); -static const u8 sDarkAuraDescription[] = _("Boosts Dark moves."); -static const u8 sFairyAuraDescription[] = _("Boosts Fairy moves."); -static const u8 sAuraBreakDescription[] = _("Reverse aura abilities."); -static const u8 sPrimordialSeaDescription[] = _("Summons heavy rain."); -static const u8 sDesolateLandDescription[] = _("Summons intense sunlight."); -static const u8 sDeltaStreamDescription[] = _("Summons strong winds."); -static const u8 sStaminaDescription[] = _("Boosts Defense when hit."); -static const u8 sWimpOutDescription[] = _("Flees at half HP."); -static const u8 sWaterCompactionDescription[] = _("Water boosts Defense."); -static const u8 sMercilessDescription[] = _("Criticals poisoned foes."); -static const u8 sShieldsDownDescription[] = _("Shell breaks at half HP."); -static const u8 sStakeoutDescription[] = _("Stronger as foes switch in."); -static const u8 sWaterBubbleDescription[] = _("Guards from fire and burns."); -static const u8 sSteelworkerDescription[] = _("Powers up Steel moves."); -static const u8 sBerserkDescription[] = _("Boosts Sp. Atk at low HP."); -static const u8 sSlushRushDescription[] = _("Raises Speed in Hail or Snow."); -static const u8 sLongReachDescription[] = _("Never makes contact."); -static const u8 sLiquidVoiceDescription[] = _("Makes sound moves Water."); -static const u8 sTriageDescription[] = _("Healing moves go first."); -static const u8 sGalvanizeDescription[] = _("Normal moves turn Electric."); -static const u8 sSurgeSurferDescription[] = _("Faster on electricity."); -static const u8 sSchoolingDescription[] = _("Forms a school when strong."); -static const u8 sDisguiseDescription[] = _("Decoy protects it once."); -static const u8 sBattleBondDescription[] = _("Changes form after a KO."); -static const u8 sPowerConstructDescription[] = _("Cells aid it when weakened."); -static const u8 sCorrosionDescription[] = _("Poisons any type."); -static const u8 sComatoseDescription[] = _("Always drowsing."); -static const u8 sQueenlyMajestyDescription[] = _("Protects from priority."); -static const u8 sInnardsOutDescription[] = _("Hurts foe when defeated."); -static const u8 sDancerDescription[] = _("Dances along with others."); -static const u8 sBatteryDescription[] = _("Boosts ally's Sp. Atk."); -static const u8 sFluffyDescription[] = _("Tougher but flammable."); -static const u8 sSoulHeartDescription[] = _("KOs raise Sp. Atk."); -static const u8 sTanglingHairDescription[] = _("Contact lowers Speed."); -static const u8 sReceiverDescription[] = _("Copies ally's ability."); -static const u8 sBeastBoostDescription[] = _("KOs boost best stat."); -static const u8 sRKSSystemDescription[] = _("Memories change its type."); -static const u8 sElectricSurgeDescription[] = _("Field becomes Electric."); -static const u8 sPsychicSurgeDescription[] = _("Field becomes weird."); -static const u8 sMistySurgeDescription[] = _("Field becomes misty."); -static const u8 sGrassySurgeDescription[] = _("Field becomes grassy."); -static const u8 sFullMetalBodyDescription[] = _("Prevents stat reduction."); -static const u8 sNeuroforceDescription[] = _("Ups “supereffective”."); -static const u8 sIntrepidSwordDescription[] = _("Ups Attack on entry."); -static const u8 sDauntlessShieldDescription[] = _("Ups Defense on entry."); -static const u8 sLiberoDescription[] = _("Changes type to move's."); -static const u8 sBallFetchDescription[] = _("Fetches failed Poké Ball."); -static const u8 sCottonDownDescription[] = _("Lower Speed of all when hit."); -static const u8 sPropellerTailDescription[] = _("Ignores foe's redirection."); -static const u8 sMirrorArmorDescription[] = _("Reflect stat decreases."); -static const u8 sGulpMissileDescription[] = _("If hit, spits prey from sea."); -static const u8 sStalwartDescription[] = _("Ignores foe's redirection."); -static const u8 sSteamEngineDescription[] = _("Fire or Water hits up Speed."); -static const u8 sPunkRockDescription[] = _("Ups and resists sound."); -static const u8 sSandSpitDescription[] = _("Creates a sandstorm if hit."); -static const u8 sIceScalesDescription[] = _("Halves special damage."); -static const u8 sRipenDescription[] = _("Doubles effect of Berries."); -static const u8 sIceFaceDescription[] = _("Hail or Snow renew free hit."); -static const u8 sPowerSpotDescription[] = _("Powers up ally moves."); -static const u8 sMimicryDescription[] = _("Changes type on terrain."); -static const u8 sScreenCleanerDescription[] = _("Removes walls of light."); -static const u8 sSteelySpiritDescription[] = _("Boosts ally's Steel moves."); -static const u8 sPerishBodyDescription[] = _("Foe faints in 3 turns if hit."); -static const u8 sWanderingSpiritDescription[] = _("Trade abilities on contact."); -static const u8 sGorillaTacticsDescription[] = _("Ups Attack and locks move."); -static const u8 sNeutralizingGasDescription[] = _("All Abilities are nullified."); -static const u8 sPastelVeilDescription[] = _("Protects team from poison."); -static const u8 sHungerSwitchDescription[] = _("Changes form each turn.");; -static const u8 sQuickDrawDescription[] = _("Moves first occasionally."); -static const u8 sUnseenFistDescription[] = _("Contact evades protection."); -static const u8 sCuriousMedicineDescription[] = _("Remove ally's stat changes."); -static const u8 sTransistorDescription[] = _("Ups Electric-type moves."); -static const u8 sDragonsMawDescription[] = _("Ups Dragon-type moves."); -static const u8 sChillingNeighDescription[] = _("KOs boost Attack stat."); -static const u8 sGrimNeighDescription[] = _("KOs boost Sp. Atk stat."); -static const u8 sAsOneIceRiderDescription[] = _("Unnerve and Chilling Neigh."); -static const u8 sAsOneShadowRiderDescription[] = _("Unnerve and Grim Neigh."); -static const u8 sLingeringAromaDescription[] = _("Spreads with contact."); -static const u8 sSeedSowerDescription[] = _("Affects terrain when hit."); -static const u8 sThermalExchangeDescription[] = _("Fire hits up Attack."); -static const u8 sAngerShellDescription[] = _("Gets angry at half HP."); -static const u8 sPurifyingSaltDescription[] = _("Protected by pure salts."); -static const u8 sWellBakedBodyDescription[] = _("Strengthened by Fire."); -static const u8 sWindRiderDescription[] = _("Ups Attack if hit by wind."); -static const u8 sGuardDogDescription[] = _("Cannot be intimidated."); -static const u8 sRockyPayloadDescription[] = _("Powers up Rock moves."); -static const u8 sWindPowerDescription[] = _("Gets charged by wind."); -static const u8 sZeroToHeroDescription[] = _("Changes form on switch out."); -static const u8 sCommanderDescription[] = _("Commands from Dondozo."); -static const u8 sElectromorphosisDescription[] = _("Gets Charged on contact."); -static const u8 sProtosynthesisDescription[] = _("Sun boosts best stat."); -static const u8 sQuarkDriveDescription[] = _("Elec. field ups best stat."); -static const u8 sGoodAsGoldDescription[] = _("Avoids status problems."); -static const u8 sVesselOfRuinDescription[] = _("Lowers foes' sp. damage."); -static const u8 sSwordOfRuinDescription[] = _("Lowers foes' defense."); -static const u8 sTabletsOfRuinDescription[] = _("Lowers foes' damage."); -static const u8 sBeadsOfRuinDescription[] = _("Lowers foes' sp. defense."); -static const u8 sOrichalcumPulseDescription[] = _("Summons sunlight in battle."); -static const u8 sHadronEngineDescription[] = _("Field becomes Electric."); -static const u8 sOpportunistDescription[] = _("Copies foe's stat change."); -static const u8 sCudChewDescription[] = _("Eats a used berry again."); -static const u8 sSharpnessDescription[] = _("Strengthens slicing moves."); -static const u8 sSupremeOverlordDescription[] = _("Inherits fallen's strength."); -static const u8 sCostarDescription[] = _("Copies ally's stat changes."); -static const u8 sToxicDebrisDescription[] = _("Throws poison spikes if hit."); -static const u8 sArmorTailDescription[] = _("Protects from priority."); -static const u8 sEarthEaterDescription[] = _("Eats ground to heal HP."); -static const u8 sMyceliumMightDescription[] = _("Status moves never fail."); -static const u8 sHospitalityDescription[] = _("Restores ally's HP."); -static const u8 sMindsEyeDescription[] = _("Keen Eye and Scrappy."); -static const u8 sEmbodyAspectTealDescription[] = _("Raises Speed."); -static const u8 sEmbodyAspectHearthflameDescription[] = _("Raises Attack."); -static const u8 sEmbodyAspectWellspringDescription[] = _("Raises Sp. Def."); -static const u8 sEmbodyAspectCornerstoneDescription[] = _("Raises Defense."); -static const u8 sToxicChainDescription[] = _("Moves can poison."); -static const u8 sSupersweetSyrupDescription[] = _("Lowers the foe's Speed."); - -#if B_EXPANDED_ABILITY_NAMES == TRUE -const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = -{ - [ABILITY_NONE] = _("-------"), - [ABILITY_STENCH] = _("Stench"), - [ABILITY_DRIZZLE] = _("Drizzle"), - [ABILITY_SPEED_BOOST] = _("Speed Boost"), - [ABILITY_BATTLE_ARMOR] = _("Battle Armor"), - [ABILITY_STURDY] = _("Sturdy"), - [ABILITY_DAMP] = _("Damp"), - [ABILITY_LIMBER] = _("Limber"), - [ABILITY_SAND_VEIL] = _("Sand Veil"), - [ABILITY_STATIC] = _("Static"), - [ABILITY_VOLT_ABSORB] = _("Volt Absorb"), - [ABILITY_WATER_ABSORB] = _("Water Absorb"), - [ABILITY_OBLIVIOUS] = _("Oblivious"), - [ABILITY_CLOUD_NINE] = _("Cloud Nine"), - [ABILITY_COMPOUND_EYES] = _("Compound Eyes"), - [ABILITY_INSOMNIA] = _("Insomnia"), - [ABILITY_COLOR_CHANGE] = _("Color Change"), - [ABILITY_IMMUNITY] = _("Immunity"), - [ABILITY_FLASH_FIRE] = _("Flash Fire"), - [ABILITY_SHIELD_DUST] = _("Shield Dust"), - [ABILITY_OWN_TEMPO] = _("Own Tempo"), - [ABILITY_SUCTION_CUPS] = _("Suction Cups"), - [ABILITY_INTIMIDATE] = _("Intimidate"), - [ABILITY_SHADOW_TAG] = _("Shadow Tag"), - [ABILITY_ROUGH_SKIN] = _("Rough Skin"), - [ABILITY_WONDER_GUARD] = _("Wonder Guard"), - [ABILITY_LEVITATE] = _("Levitate"), - [ABILITY_EFFECT_SPORE] = _("Effect Spore"), - [ABILITY_SYNCHRONIZE] = _("Synchronize"), - [ABILITY_CLEAR_BODY] = _("Clear Body"), - [ABILITY_NATURAL_CURE] = _("Natural Cure"), - [ABILITY_LIGHTNING_ROD] = _("Lightning Rod"), - [ABILITY_SERENE_GRACE] = _("Serene Grace"), - [ABILITY_SWIFT_SWIM] = _("Swift Swim"), - [ABILITY_CHLOROPHYLL] = _("Chlorophyll"), - [ABILITY_ILLUMINATE] = _("Illuminate"), - [ABILITY_TRACE] = _("Trace"), - [ABILITY_HUGE_POWER] = _("Huge Power"), - [ABILITY_POISON_POINT] = _("Poison Point"), - [ABILITY_INNER_FOCUS] = _("Inner Focus"), - [ABILITY_MAGMA_ARMOR] = _("Magma Armor"), - [ABILITY_WATER_VEIL] = _("Water Veil"), - [ABILITY_MAGNET_PULL] = _("Magnet Pull"), - [ABILITY_SOUNDPROOF] = _("Soundproof"), - [ABILITY_RAIN_DISH] = _("Rain Dish"), - [ABILITY_SAND_STREAM] = _("Sand Stream"), - [ABILITY_PRESSURE] = _("Pressure"), - [ABILITY_THICK_FAT] = _("Thick Fat"), - [ABILITY_EARLY_BIRD] = _("Early Bird"), - [ABILITY_FLAME_BODY] = _("Flame Body"), - [ABILITY_RUN_AWAY] = _("Run Away"), - [ABILITY_KEEN_EYE] = _("Keen Eye"), - [ABILITY_HYPER_CUTTER] = _("Hyper Cutter"), - [ABILITY_PICKUP] = _("Pickup"), - [ABILITY_TRUANT] = _("Truant"), - [ABILITY_HUSTLE] = _("Hustle"), - [ABILITY_CUTE_CHARM] = _("Cute Charm"), - [ABILITY_PLUS] = _("Plus"), - [ABILITY_MINUS] = _("Minus"), - [ABILITY_FORECAST] = _("Forecast"), - [ABILITY_STICKY_HOLD] = _("Sticky Hold"), - [ABILITY_SHED_SKIN] = _("Shed Skin"), - [ABILITY_GUTS] = _("Guts"), - [ABILITY_MARVEL_SCALE] = _("Marvel Scale"), - [ABILITY_LIQUID_OOZE] = _("Liquid Ooze"), - [ABILITY_OVERGROW] = _("Overgrow"), - [ABILITY_BLAZE] = _("Blaze"), - [ABILITY_TORRENT] = _("Torrent"), - [ABILITY_SWARM] = _("Swarm"), - [ABILITY_ROCK_HEAD] = _("Rock Head"), - [ABILITY_DROUGHT] = _("Drought"), - [ABILITY_ARENA_TRAP] = _("Arena Trap"), - [ABILITY_VITAL_SPIRIT] = _("Vital Spirit"), - [ABILITY_WHITE_SMOKE] = _("White Smoke"), - [ABILITY_PURE_POWER] = _("Pure Power"), - [ABILITY_SHELL_ARMOR] = _("Shell Armor"), - [ABILITY_AIR_LOCK] = _("Air Lock"), - [ABILITY_TANGLED_FEET] = _("Tangled Feet"), - [ABILITY_MOTOR_DRIVE] = _("Motor Drive"), - [ABILITY_RIVALRY] = _("Rivalry"), - [ABILITY_STEADFAST] = _("Steadfast"), - [ABILITY_SNOW_CLOAK] = _("Snow Cloak"), - [ABILITY_GLUTTONY] = _("Gluttony"), - [ABILITY_ANGER_POINT] = _("Anger Point"), - [ABILITY_UNBURDEN] = _("Unburden"), - [ABILITY_HEATPROOF] = _("Heatproof"), - [ABILITY_SIMPLE] = _("Simple"), - [ABILITY_DRY_SKIN] = _("Dry Skin"), - [ABILITY_DOWNLOAD] = _("Download"), - [ABILITY_IRON_FIST] = _("Iron Fist"), - [ABILITY_POISON_HEAL] = _("Poison Heal"), - [ABILITY_ADAPTABILITY] = _("Adaptability"), - [ABILITY_SKILL_LINK] = _("Skill Link"), - [ABILITY_HYDRATION] = _("Hydration"), - [ABILITY_SOLAR_POWER] = _("Solar Power"), - [ABILITY_QUICK_FEET] = _("Quick Feet"), - [ABILITY_NORMALIZE] = _("Normalize"), - [ABILITY_SNIPER] = _("Sniper"), - [ABILITY_MAGIC_GUARD] = _("Magic Guard"), - [ABILITY_NO_GUARD] = _("No Guard"), - [ABILITY_STALL] = _("Stall"), - [ABILITY_TECHNICIAN] = _("Technician"), - [ABILITY_LEAF_GUARD] = _("Leaf Guard"), - [ABILITY_KLUTZ] = _("Klutz"), - [ABILITY_MOLD_BREAKER] = _("Mold Breaker"), - [ABILITY_SUPER_LUCK] = _("Super Luck"), - [ABILITY_AFTERMATH] = _("Aftermath"), - [ABILITY_ANTICIPATION] = _("Anticipation"), - [ABILITY_FOREWARN] = _("Forewarn"), - [ABILITY_UNAWARE] = _("Unaware"), - [ABILITY_TINTED_LENS] = _("Tinted Lens"), - [ABILITY_FILTER] = _("Filter"), - [ABILITY_SLOW_START] = _("Slow Start"), - [ABILITY_SCRAPPY] = _("Scrappy"), - [ABILITY_STORM_DRAIN] = _("Storm Drain"), - [ABILITY_ICE_BODY] = _("Ice Body"), - [ABILITY_SOLID_ROCK] = _("Solid Rock"), - [ABILITY_SNOW_WARNING] = _("Snow Warning"), - [ABILITY_HONEY_GATHER] = _("Honey Gather"), - [ABILITY_FRISK] = _("Frisk"), - [ABILITY_RECKLESS] = _("Reckless"), - [ABILITY_MULTITYPE] = _("Multitype"), - [ABILITY_FLOWER_GIFT] = _("Flower Gift"), - [ABILITY_BAD_DREAMS] = _("Bad Dreams"), - [ABILITY_PICKPOCKET] = _("Pickpocket"), - [ABILITY_SHEER_FORCE] = _("Sheer Force"), - [ABILITY_CONTRARY] = _("Contrary"), - [ABILITY_UNNERVE] = _("Unnerve"), - [ABILITY_DEFIANT] = _("Defiant"), - [ABILITY_DEFEATIST] = _("Defeatist"), - [ABILITY_CURSED_BODY] = _("Cursed Body"), - [ABILITY_HEALER] = _("Healer"), - [ABILITY_FRIEND_GUARD] = _("Friend Guard"), - [ABILITY_WEAK_ARMOR] = _("Weak Armor"), - [ABILITY_HEAVY_METAL] = _("Heavy Metal"), - [ABILITY_LIGHT_METAL] = _("Light Metal"), - [ABILITY_MULTISCALE] = _("Multiscale"), - [ABILITY_TOXIC_BOOST] = _("Toxic Boost"), - [ABILITY_FLARE_BOOST] = _("Flare Boost"), - [ABILITY_HARVEST] = _("Harvest"), - [ABILITY_TELEPATHY] = _("Telepathy"), - [ABILITY_MOODY] = _("Moody"), - [ABILITY_OVERCOAT] = _("Overcoat"), - [ABILITY_POISON_TOUCH] = _("Poison Touch"), - [ABILITY_REGENERATOR] = _("Regenerator"), - [ABILITY_BIG_PECKS] = _("Big Pecks"), - [ABILITY_SAND_RUSH] = _("Sand Rush"), - [ABILITY_WONDER_SKIN] = _("Wonder Skin"), - [ABILITY_ANALYTIC] = _("Analytic"), - [ABILITY_ILLUSION] = _("Illusion"), - [ABILITY_IMPOSTER] = _("Imposter"), - [ABILITY_INFILTRATOR] = _("Infiltrator"), - [ABILITY_MUMMY] = _("Mummy"), - [ABILITY_MOXIE] = _("Moxie"), - [ABILITY_JUSTIFIED] = _("Justified"), - [ABILITY_RATTLED] = _("Rattled"), - [ABILITY_MAGIC_BOUNCE] = _("Magic Bounce"), - [ABILITY_SAP_SIPPER] = _("Sap Sipper"), - [ABILITY_PRANKSTER] = _("Prankster"), - [ABILITY_SAND_FORCE] = _("Sand Force"), - [ABILITY_IRON_BARBS] = _("Iron Barbs"), - [ABILITY_ZEN_MODE] = _("Zen Mode"), - [ABILITY_VICTORY_STAR] = _("Victory Star"), - [ABILITY_TURBOBLAZE] = _("Turboblaze"), - [ABILITY_TERAVOLT] = _("Teravolt"), - [ABILITY_AROMA_VEIL] = _("Aroma Veil"), - [ABILITY_FLOWER_VEIL] = _("Flower Veil"), - [ABILITY_CHEEK_POUCH] = _("Cheek Pouch"), - [ABILITY_PROTEAN] = _("Protean"), - [ABILITY_FUR_COAT] = _("Fur Coat"), - [ABILITY_MAGICIAN] = _("Magician"), - [ABILITY_BULLETPROOF] = _("Bulletproof"), - [ABILITY_COMPETITIVE] = _("Competitive"), - [ABILITY_STRONG_JAW] = _("Strong Jaw"), - [ABILITY_REFRIGERATE] = _("Refrigerate"), - [ABILITY_SWEET_VEIL] = _("Sweet Veil"), - [ABILITY_STANCE_CHANGE] = _("Stance Change"), - [ABILITY_GALE_WINGS] = _("Gale Wings"), - [ABILITY_MEGA_LAUNCHER] = _("Mega Launcher"), - [ABILITY_GRASS_PELT] = _("Grass Pelt"), - [ABILITY_SYMBIOSIS] = _("Symbiosis"), - [ABILITY_TOUGH_CLAWS] = _("Tough Claws"), - [ABILITY_PIXILATE] = _("Pixilate"), - [ABILITY_GOOEY] = _("Gooey"), - [ABILITY_AERILATE] = _("Aerilate"), - [ABILITY_PARENTAL_BOND] = _("Parental Bond"), - [ABILITY_DARK_AURA] = _("Dark Aura"), - [ABILITY_FAIRY_AURA] = _("Fairy Aura"), - [ABILITY_AURA_BREAK] = _("Aura Break"), - [ABILITY_PRIMORDIAL_SEA] = _("Primordial Sea"), - [ABILITY_DESOLATE_LAND] = _("Desolate Land"), - [ABILITY_DELTA_STREAM] = _("Delta Stream"), - [ABILITY_STAMINA] = _("Stamina"), - [ABILITY_WIMP_OUT] = _("Wimp Out"), - [ABILITY_EMERGENCY_EXIT] = _("Emergency Exit"), - [ABILITY_WATER_COMPACTION] = _("Water Compaction"), - [ABILITY_MERCILESS] = _("Merciless"), - [ABILITY_SHIELDS_DOWN] = _("Shields Down"), - [ABILITY_STAKEOUT] = _("Stakeout"), - [ABILITY_WATER_BUBBLE] = _("Water Bubble"), - [ABILITY_STEELWORKER] = _("Steelworker"), - [ABILITY_BERSERK] = _("Berserk"), - [ABILITY_SLUSH_RUSH] = _("Slush Rush"), - [ABILITY_LONG_REACH] = _("Long Reach"), - [ABILITY_LIQUID_VOICE] = _("Liquid Voice"), - [ABILITY_TRIAGE] = _("Triage"), - [ABILITY_GALVANIZE] = _("Galvanize"), - [ABILITY_SURGE_SURFER] = _("Surge Surfer"), - [ABILITY_SCHOOLING] = _("Schooling"), - [ABILITY_DISGUISE] = _("Disguise"), - [ABILITY_BATTLE_BOND] = _("Battle Bond"), - [ABILITY_POWER_CONSTRUCT] = _("Power Construct"), - [ABILITY_CORROSION] = _("Corrosion"), - [ABILITY_COMATOSE] = _("Comatose"), - [ABILITY_QUEENLY_MAJESTY] = _("Queenly Majesty"), - [ABILITY_INNARDS_OUT] = _("Innards Out"), - [ABILITY_DANCER] = _("Dancer"), - [ABILITY_BATTERY] = _("Battery"), - [ABILITY_FLUFFY] = _("Fluffy"), - [ABILITY_DAZZLING] = _("Dazzling"), - [ABILITY_SOUL_HEART] = _("Soul-Heart"), - [ABILITY_TANGLING_HAIR] = _("Tangling Hair"), - [ABILITY_RECEIVER] = _("Receiver"), - [ABILITY_POWER_OF_ALCHEMY] = _("Power Of Alchemy"), - [ABILITY_BEAST_BOOST] = _("Beast Boost"), - [ABILITY_RKS_SYSTEM] = _("RKS System"), - [ABILITY_ELECTRIC_SURGE] = _("Electric Surge"), - [ABILITY_PSYCHIC_SURGE] = _("Psychic Surge"), - [ABILITY_MISTY_SURGE] = _("Misty Surge"), - [ABILITY_GRASSY_SURGE] = _("Grassy Surge"), - [ABILITY_FULL_METAL_BODY] = _("Full Metal Body"), - [ABILITY_SHADOW_SHIELD] = _("Shadow Shield"), - [ABILITY_PRISM_ARMOR] = _("Prism Armor"), - [ABILITY_NEUROFORCE] = _("Neuroforce"), - [ABILITY_INTREPID_SWORD] = _("Intrepid Sword"), - [ABILITY_DAUNTLESS_SHIELD] = _("Dauntless Shield"), - [ABILITY_LIBERO] = _("Libero"), - [ABILITY_BALL_FETCH] = _("Ball Fetch"), - [ABILITY_COTTON_DOWN] = _("Cotton Down"), - [ABILITY_PROPELLER_TAIL] = _("Propeller Tail"), - [ABILITY_MIRROR_ARMOR] = _("Mirror Armor"), - [ABILITY_GULP_MISSILE] = _("Gulp Missile"), - [ABILITY_STALWART] = _("Stalwart"), - [ABILITY_STEAM_ENGINE] = _("Steam Engine"), - [ABILITY_PUNK_ROCK] = _("Punk Rock"), - [ABILITY_SAND_SPIT] = _("Sand Spit"), - [ABILITY_ICE_SCALES] = _("Ice Scales"), - [ABILITY_RIPEN] = _("Ripen"), - [ABILITY_ICE_FACE] = _("Ice Face"), - [ABILITY_POWER_SPOT] = _("Power Spot"), - [ABILITY_MIMICRY] = _("Mimicry"), - [ABILITY_SCREEN_CLEANER] = _("Screen Cleaner"), - [ABILITY_STEELY_SPIRIT] = _("Steely Spirit"), - [ABILITY_PERISH_BODY] = _("Perish Body"), - [ABILITY_WANDERING_SPIRIT] = _("Wandering Spirit"), - [ABILITY_GORILLA_TACTICS] = _("Gorilla Tactics"), - [ABILITY_NEUTRALIZING_GAS] = _("Neutralizing Gas"), - [ABILITY_PASTEL_VEIL] = _("Pastel Veil"), - [ABILITY_HUNGER_SWITCH] = _("Hunger Switch"), - [ABILITY_QUICK_DRAW] = _("Quick Draw"), - [ABILITY_UNSEEN_FIST] = _("Unseen Fist"), - [ABILITY_CURIOUS_MEDICINE] = _("Curious Medicine"), - [ABILITY_TRANSISTOR] = _("Transistor"), - [ABILITY_DRAGONS_MAW] = _("Dragon's Maw"), - [ABILITY_CHILLING_NEIGH] = _("Chilling Neigh"), - [ABILITY_GRIM_NEIGH] = _("Grim Neigh"), - [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), - [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), - [ABILITY_LINGERING_AROMA] = _("Lingering Aroma"), - [ABILITY_SEED_SOWER] = _("Seed Sower"), - [ABILITY_THERMAL_EXCHANGE] = _("Thermal Exchange"), - [ABILITY_ANGER_SHELL] = _("Anger Shell"), - [ABILITY_PURIFYING_SALT] = _("Purifying Salt"), - [ABILITY_WELL_BAKED_BODY] = _("Well-Baked Body"), - [ABILITY_WIND_RIDER] = _("Wind Rider"), - [ABILITY_GUARD_DOG] = _("Guard Dog"), - [ABILITY_ROCKY_PAYLOAD] = _("Rocky Payload"), - [ABILITY_WIND_POWER] = _("Wind Power"), - [ABILITY_ZERO_TO_HERO] = _("Zero to Hero"), - [ABILITY_COMMANDER] = _("Commander"), - [ABILITY_ELECTROMORPHOSIS] = _("Electromorphosis"), - [ABILITY_PROTOSYNTHESIS] = _("Protosynthesis"), - [ABILITY_QUARK_DRIVE] = _("Quark Drive"), - [ABILITY_GOOD_AS_GOLD] = _("Good as Gold"), - [ABILITY_VESSEL_OF_RUIN] = _("Vessel of Ruin"), - [ABILITY_SWORD_OF_RUIN] = _("Sword of Ruin"), - [ABILITY_TABLETS_OF_RUIN] = _("Tablets of Ruin"), - [ABILITY_BEADS_OF_RUIN] = _("Beads of Ruin"), - [ABILITY_ORICHALCUM_PULSE] = _("Orichalcum Pulse"), - [ABILITY_HADRON_ENGINE] = _("Hadron Engine"), - [ABILITY_OPPORTUNIST] = _("Opportunist"), - [ABILITY_CUD_CHEW] = _("Cud Chew"), - [ABILITY_SHARPNESS] = _("Sharpness"), - [ABILITY_SUPREME_OVERLORD] = _("Supreme Overlord"), - [ABILITY_COSTAR] = _("Costar"), - [ABILITY_TOXIC_DEBRIS] = _("Toxic Debris"), - [ABILITY_ARMOR_TAIL] = _("Armor Tail"), - [ABILITY_EARTH_EATER] = _("Earth Eater"), - [ABILITY_MYCELIUM_MIGHT] = _("Mycelium Might"), - [ABILITY_HOSPITALITY] = _("Hospitality"), - [ABILITY_MINDS_EYE] = _("Mind's Eye"), - [ABILITY_EMBODY_ASPECT_TEAL] = _("Embody Aspect"), - [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = _("Embody Aspect"), - [ABILITY_EMBODY_ASPECT_WELLSPRING] = _("Embody Aspect"), - [ABILITY_EMBODY_ASPECT_CORNERSTONE] = _("Embody Aspect"), - [ABILITY_TOXIC_CHAIN] = _("Toxic Chain"), - [ABILITY_SUPERSWEET_SYRUP] = _("Supersweet Syrup"), -}; -#else // 12 characters -const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = -{ - [ABILITY_NONE] = _("-------"), - [ABILITY_STENCH] = _("Stench"), - [ABILITY_DRIZZLE] = _("Drizzle"), - [ABILITY_SPEED_BOOST] = _("Speed Boost"), - [ABILITY_BATTLE_ARMOR] = _("Battle Armor"), - [ABILITY_STURDY] = _("Sturdy"), - [ABILITY_DAMP] = _("Damp"), - [ABILITY_LIMBER] = _("Limber"), - [ABILITY_SAND_VEIL] = _("Sand Veil"), - [ABILITY_STATIC] = _("Static"), - [ABILITY_VOLT_ABSORB] = _("Volt Absorb"), - [ABILITY_WATER_ABSORB] = _("Water Absorb"), - [ABILITY_OBLIVIOUS] = _("Oblivious"), - [ABILITY_CLOUD_NINE] = _("Cloud Nine"), - [ABILITY_COMPOUND_EYES] = _("CompoundEyes"), - [ABILITY_INSOMNIA] = _("Insomnia"), - [ABILITY_COLOR_CHANGE] = _("Color Change"), - [ABILITY_IMMUNITY] = _("Immunity"), - [ABILITY_FLASH_FIRE] = _("Flash Fire"), - [ABILITY_SHIELD_DUST] = _("Shield Dust"), - [ABILITY_OWN_TEMPO] = _("Own Tempo"), - [ABILITY_SUCTION_CUPS] = _("Suction Cups"), - [ABILITY_INTIMIDATE] = _("Intimidate"), - [ABILITY_SHADOW_TAG] = _("Shadow Tag"), - [ABILITY_ROUGH_SKIN] = _("Rough Skin"), - [ABILITY_WONDER_GUARD] = _("Wonder Guard"), - [ABILITY_LEVITATE] = _("Levitate"), - [ABILITY_EFFECT_SPORE] = _("Effect Spore"), - [ABILITY_SYNCHRONIZE] = _("Synchronize"), - [ABILITY_CLEAR_BODY] = _("Clear Body"), - [ABILITY_NATURAL_CURE] = _("Natural Cure"), - [ABILITY_LIGHTNING_ROD] = _("LightningRod"), - [ABILITY_SERENE_GRACE] = _("Serene Grace"), - [ABILITY_SWIFT_SWIM] = _("Swift Swim"), - [ABILITY_CHLOROPHYLL] = _("Chlorophyll"), - [ABILITY_ILLUMINATE] = _("Illuminate"), - [ABILITY_TRACE] = _("Trace"), - [ABILITY_HUGE_POWER] = _("Huge Power"), - [ABILITY_POISON_POINT] = _("Poison Point"), - [ABILITY_INNER_FOCUS] = _("Inner Focus"), - [ABILITY_MAGMA_ARMOR] = _("Magma Armor"), - [ABILITY_WATER_VEIL] = _("Water Veil"), - [ABILITY_MAGNET_PULL] = _("Magnet Pull"), - [ABILITY_SOUNDPROOF] = _("Soundproof"), - [ABILITY_RAIN_DISH] = _("Rain Dish"), - [ABILITY_SAND_STREAM] = _("Sand Stream"), - [ABILITY_PRESSURE] = _("Pressure"), - [ABILITY_THICK_FAT] = _("Thick Fat"), - [ABILITY_EARLY_BIRD] = _("Early Bird"), - [ABILITY_FLAME_BODY] = _("Flame Body"), - [ABILITY_RUN_AWAY] = _("Run Away"), - [ABILITY_KEEN_EYE] = _("Keen Eye"), - [ABILITY_HYPER_CUTTER] = _("Hyper Cutter"), - [ABILITY_PICKUP] = _("Pickup"), - [ABILITY_TRUANT] = _("Truant"), - [ABILITY_HUSTLE] = _("Hustle"), - [ABILITY_CUTE_CHARM] = _("Cute Charm"), - [ABILITY_PLUS] = _("Plus"), - [ABILITY_MINUS] = _("Minus"), - [ABILITY_FORECAST] = _("Forecast"), - [ABILITY_STICKY_HOLD] = _("Sticky Hold"), - [ABILITY_SHED_SKIN] = _("Shed Skin"), - [ABILITY_GUTS] = _("Guts"), - [ABILITY_MARVEL_SCALE] = _("Marvel Scale"), - [ABILITY_LIQUID_OOZE] = _("Liquid Ooze"), - [ABILITY_OVERGROW] = _("Overgrow"), - [ABILITY_BLAZE] = _("Blaze"), - [ABILITY_TORRENT] = _("Torrent"), - [ABILITY_SWARM] = _("Swarm"), - [ABILITY_ROCK_HEAD] = _("Rock Head"), - [ABILITY_DROUGHT] = _("Drought"), - [ABILITY_ARENA_TRAP] = _("Arena Trap"), - [ABILITY_VITAL_SPIRIT] = _("Vital Spirit"), - [ABILITY_WHITE_SMOKE] = _("White Smoke"), - [ABILITY_PURE_POWER] = _("Pure Power"), - [ABILITY_SHELL_ARMOR] = _("Shell Armor"), - [ABILITY_AIR_LOCK] = _("Air Lock"), - [ABILITY_TANGLED_FEET] = _("Tangled Feet"), - [ABILITY_MOTOR_DRIVE] = _("Motor Drive"), - [ABILITY_RIVALRY] = _("Rivalry"), - [ABILITY_STEADFAST] = _("Steadfast"), - [ABILITY_SNOW_CLOAK] = _("Snow Cloak"), - [ABILITY_GLUTTONY] = _("Gluttony"), - [ABILITY_ANGER_POINT] = _("Anger Point"), - [ABILITY_UNBURDEN] = _("Unburden"), - [ABILITY_HEATPROOF] = _("Heatproof"), - [ABILITY_SIMPLE] = _("Simple"), - [ABILITY_DRY_SKIN] = _("Dry Skin"), - [ABILITY_DOWNLOAD] = _("Download"), - [ABILITY_IRON_FIST] = _("Iron Fist"), - [ABILITY_POISON_HEAL] = _("Poison Heal"), - [ABILITY_ADAPTABILITY] = _("Adaptability"), - [ABILITY_SKILL_LINK] = _("Skill Link"), - [ABILITY_HYDRATION] = _("Hydration"), - [ABILITY_SOLAR_POWER] = _("Solar Power"), - [ABILITY_QUICK_FEET] = _("Quick Feet"), - [ABILITY_NORMALIZE] = _("Normalize"), - [ABILITY_SNIPER] = _("Sniper"), - [ABILITY_MAGIC_GUARD] = _("Magic Guard"), - [ABILITY_NO_GUARD] = _("No Guard"), - [ABILITY_STALL] = _("Stall"), - [ABILITY_TECHNICIAN] = _("Technician"), - [ABILITY_LEAF_GUARD] = _("Leaf Guard"), - [ABILITY_KLUTZ] = _("Klutz"), - [ABILITY_MOLD_BREAKER] = _("Mold Breaker"), - [ABILITY_SUPER_LUCK] = _("Super Luck"), - [ABILITY_AFTERMATH] = _("Aftermath"), - [ABILITY_ANTICIPATION] = _("Anticipation"), - [ABILITY_FOREWARN] = _("Forewarn"), - [ABILITY_UNAWARE] = _("Unaware"), - [ABILITY_TINTED_LENS] = _("Tinted Lens"), - [ABILITY_FILTER] = _("Filter"), - [ABILITY_SLOW_START] = _("Slow Start"), - [ABILITY_SCRAPPY] = _("Scrappy"), - [ABILITY_STORM_DRAIN] = _("Storm Drain"), - [ABILITY_ICE_BODY] = _("Ice Body"), - [ABILITY_SOLID_ROCK] = _("Solid Rock"), - [ABILITY_SNOW_WARNING] = _("Snow Warning"), - [ABILITY_HONEY_GATHER] = _("Honey Gather"), - [ABILITY_FRISK] = _("Frisk"), - [ABILITY_RECKLESS] = _("Reckless"), - [ABILITY_MULTITYPE] = _("Multitype"), - [ABILITY_FLOWER_GIFT] = _("Flower Gift"), - [ABILITY_BAD_DREAMS] = _("Bad Dreams"), - [ABILITY_PICKPOCKET] = _("Pickpocket"), - [ABILITY_SHEER_FORCE] = _("Sheer Force"), - [ABILITY_CONTRARY] = _("Contrary"), - [ABILITY_UNNERVE] = _("Unnerve"), - [ABILITY_DEFIANT] = _("Defiant"), - [ABILITY_DEFEATIST] = _("Defeatist"), - [ABILITY_CURSED_BODY] = _("Cursed Body"), - [ABILITY_HEALER] = _("Healer"), - [ABILITY_FRIEND_GUARD] = _("Friend Guard"), - [ABILITY_WEAK_ARMOR] = _("Weak Armor"), - [ABILITY_HEAVY_METAL] = _("Heavy Metal"), - [ABILITY_LIGHT_METAL] = _("Light Metal"), - [ABILITY_MULTISCALE] = _("Multiscale"), - [ABILITY_TOXIC_BOOST] = _("Toxic Boost"), - [ABILITY_FLARE_BOOST] = _("Flare Boost"), - [ABILITY_HARVEST] = _("Harvest"), - [ABILITY_TELEPATHY] = _("Telepathy"), - [ABILITY_MOODY] = _("Moody"), - [ABILITY_OVERCOAT] = _("Overcoat"), - [ABILITY_POISON_TOUCH] = _("Poison Touch"), - [ABILITY_REGENERATOR] = _("Regenerator"), - [ABILITY_BIG_PECKS] = _("Big Pecks"), - [ABILITY_SAND_RUSH] = _("Sand Rush"), - [ABILITY_WONDER_SKIN] = _("Wonder Skin"), - [ABILITY_ANALYTIC] = _("Analytic"), - [ABILITY_ILLUSION] = _("Illusion"), - [ABILITY_IMPOSTER] = _("Imposter"), - [ABILITY_INFILTRATOR] = _("Infiltrator"), - [ABILITY_MUMMY] = _("Mummy"), - [ABILITY_MOXIE] = _("Moxie"), - [ABILITY_JUSTIFIED] = _("Justified"), - [ABILITY_RATTLED] = _("Rattled"), - [ABILITY_MAGIC_BOUNCE] = _("Magic Bounce"), - [ABILITY_SAP_SIPPER] = _("Sap Sipper"), - [ABILITY_PRANKSTER] = _("Prankster"), - [ABILITY_SAND_FORCE] = _("Sand Force"), - [ABILITY_IRON_BARBS] = _("Iron Barbs"), - [ABILITY_ZEN_MODE] = _("Zen Mode"), - [ABILITY_VICTORY_STAR] = _("Victory Star"), - [ABILITY_TURBOBLAZE] = _("Turboblaze"), - [ABILITY_TERAVOLT] = _("Teravolt"), - [ABILITY_AROMA_VEIL] = _("Aroma Veil"), - [ABILITY_FLOWER_VEIL] = _("Flower Veil"), - [ABILITY_CHEEK_POUCH] = _("Cheek Pouch"), - [ABILITY_PROTEAN] = _("Protean"), - [ABILITY_FUR_COAT] = _("Fur Coat"), - [ABILITY_MAGICIAN] = _("Magician"), - [ABILITY_BULLETPROOF] = _("Bulletproof"), - [ABILITY_COMPETITIVE] = _("Competitive"), - [ABILITY_STRONG_JAW] = _("Strong Jaw"), - [ABILITY_REFRIGERATE] = _("Refrigerate"), - [ABILITY_SWEET_VEIL] = _("Sweet Veil"), - [ABILITY_STANCE_CHANGE] = _("StanceChange"), - [ABILITY_GALE_WINGS] = _("Gale Wings"), - [ABILITY_MEGA_LAUNCHER] = _("MegaLauncher"), - [ABILITY_GRASS_PELT] = _("Grass Pelt"), - [ABILITY_SYMBIOSIS] = _("Symbiosis"), - [ABILITY_TOUGH_CLAWS] = _("Tough Claws"), - [ABILITY_PIXILATE] = _("Pixilate"), - [ABILITY_GOOEY] = _("Gooey"), - [ABILITY_AERILATE] = _("Aerilate"), - [ABILITY_PARENTAL_BOND] = _("ParentalBond"), - [ABILITY_DARK_AURA] = _("Dark Aura"), - [ABILITY_FAIRY_AURA] = _("Fairy Aura"), - [ABILITY_AURA_BREAK] = _("Aura Break"), - [ABILITY_PRIMORDIAL_SEA] = _("PrimrdialSea"), - [ABILITY_DESOLATE_LAND] = _("DesolateLand"), - [ABILITY_DELTA_STREAM] = _("Delta Stream"), - [ABILITY_STAMINA] = _("Stamina"), - [ABILITY_WIMP_OUT] = _("Wimp Out"), - [ABILITY_EMERGENCY_EXIT] = _("EmergncyExit"), - [ABILITY_WATER_COMPACTION] = _("WtrCmpaction"), - [ABILITY_MERCILESS] = _("Merciless"), - [ABILITY_SHIELDS_DOWN] = _("Shields Down"), - [ABILITY_STAKEOUT] = _("Stakeout"), - [ABILITY_WATER_BUBBLE] = _("Water Bubble"), - [ABILITY_STEELWORKER] = _("Steelworker"), - [ABILITY_BERSERK] = _("Berserk"), - [ABILITY_SLUSH_RUSH] = _("Slush Rush"), - [ABILITY_LONG_REACH] = _("Long Reach"), - [ABILITY_LIQUID_VOICE] = _("Liquid Voice"), - [ABILITY_TRIAGE] = _("Triage"), - [ABILITY_GALVANIZE] = _("Galvanize"), - [ABILITY_SURGE_SURFER] = _("Surge Surfer"), - [ABILITY_SCHOOLING] = _("Schooling"), - [ABILITY_DISGUISE] = _("Disguise"), - [ABILITY_BATTLE_BOND] = _("Battle Bond"), - [ABILITY_POWER_CONSTRUCT] = _("PwrConstruct"), - [ABILITY_CORROSION] = _("Corrosion"), - [ABILITY_COMATOSE] = _("Comatose"), - [ABILITY_QUEENLY_MAJESTY] = _("QueenlyMjsty"), - [ABILITY_INNARDS_OUT] = _("Innards Out"), - [ABILITY_DANCER] = _("Dancer"), - [ABILITY_BATTERY] = _("Battery"), - [ABILITY_FLUFFY] = _("Fluffy"), - [ABILITY_DAZZLING] = _("Dazzling"), - [ABILITY_SOUL_HEART] = _("Soul-Heart"), - [ABILITY_TANGLING_HAIR] = _("TanglingHair"), - [ABILITY_RECEIVER] = _("Receiver"), - [ABILITY_POWER_OF_ALCHEMY] = _("PwrOfAlchemy"), - [ABILITY_BEAST_BOOST] = _("Beast Boost"), - [ABILITY_RKS_SYSTEM] = _("RKS System"), - [ABILITY_ELECTRIC_SURGE] = _("ElectrcSurge"), - [ABILITY_PSYCHIC_SURGE] = _("PsychicSurge"), - [ABILITY_MISTY_SURGE] = _("Misty Surge"), - [ABILITY_GRASSY_SURGE] = _("Grassy Surge"), - [ABILITY_FULL_METAL_BODY] = _("FullMetalBdy"), - [ABILITY_SHADOW_SHIELD] = _("ShadowShield"), - [ABILITY_PRISM_ARMOR] = _("Prism Armor"), - [ABILITY_NEUROFORCE] = _("Neuroforce"), - [ABILITY_INTREPID_SWORD] = _("IntrepidSwrd"), - [ABILITY_DAUNTLESS_SHIELD] = _("DauntlssShld"), - [ABILITY_LIBERO] = _("Libero"), - [ABILITY_BALL_FETCH] = _("Ball Fetch"), - [ABILITY_COTTON_DOWN] = _("Cotton Down"), - [ABILITY_PROPELLER_TAIL] = _("PropellrTail"), - [ABILITY_MIRROR_ARMOR] = _("Mirror Armor"), - [ABILITY_GULP_MISSILE] = _("Gulp Missile"), - [ABILITY_STALWART] = _("Stalwart"), - [ABILITY_STEAM_ENGINE] = _("Steam Engine"), - [ABILITY_PUNK_ROCK] = _("Punk Rock"), - [ABILITY_SAND_SPIT] = _("Sand Spit"), - [ABILITY_ICE_SCALES] = _("Ice Scales"), - [ABILITY_RIPEN] = _("Ripen"), - [ABILITY_ICE_FACE] = _("Ice Face"), - [ABILITY_POWER_SPOT] = _("Power Spot"), - [ABILITY_MIMICRY] = _("Mimicry"), - [ABILITY_SCREEN_CLEANER] = _("ScreenCleanr"), - [ABILITY_STEELY_SPIRIT] = _("SteelySpirit"), - [ABILITY_PERISH_BODY] = _("Perish Body"), - [ABILITY_WANDERING_SPIRIT] = _("WandrngSprit"), - [ABILITY_GORILLA_TACTICS] = _("GorillaTacti"), - [ABILITY_NEUTRALIZING_GAS] = _("NeutrlzngGas"), - [ABILITY_PASTEL_VEIL] = _("Pastel Veil"), - [ABILITY_HUNGER_SWITCH] = _("HungerSwitch"), - [ABILITY_QUICK_DRAW] = _("Quick Draw"), - [ABILITY_UNSEEN_FIST] = _("Unseen Fist"), - [ABILITY_CURIOUS_MEDICINE] = _("CuriusMedicn"), - [ABILITY_TRANSISTOR] = _("Transistor"), - [ABILITY_DRAGONS_MAW] = _("Dragon's Maw"), - [ABILITY_CHILLING_NEIGH] = _("ChillngNeigh"), - [ABILITY_GRIM_NEIGH] = _("Grim Neigh"), - [ABILITY_AS_ONE_ICE_RIDER] = _("As One"), - [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), - [ABILITY_LINGERING_AROMA] = _("LngerngAroma"), - [ABILITY_SEED_SOWER] = _("Seed Sower"), - [ABILITY_THERMAL_EXCHANGE] = _("ThrmlExchnge"), - [ABILITY_ANGER_SHELL] = _("Anger Shell"), - [ABILITY_PURIFYING_SALT] = _("PurfyingSalt"), - [ABILITY_WELL_BAKED_BODY] = _("WellBakedBdy"), - [ABILITY_WIND_RIDER] = _("Wind Rider"), - [ABILITY_GUARD_DOG] = _("Guard Dog"), - [ABILITY_ROCKY_PAYLOAD] = _("RockyPayload"), - [ABILITY_WIND_POWER] = _("Wind Power"), - [ABILITY_ZERO_TO_HERO] = _("Zero to Hero"), - [ABILITY_COMMANDER] = _("Commander"), - [ABILITY_ELECTROMORPHOSIS] = _("Elecmrphosis"), - [ABILITY_PROTOSYNTHESIS] = _("Protosnthsis"), - [ABILITY_QUARK_DRIVE] = _("Quark Drive"), - [ABILITY_GOOD_AS_GOLD] = _("Good as Gold"), - [ABILITY_VESSEL_OF_RUIN] = _("VesselOfRuin"), - [ABILITY_SWORD_OF_RUIN] = _("SwordOfRuin"), - [ABILITY_TABLETS_OF_RUIN] = _("TabltsOfRuin"), - [ABILITY_BEADS_OF_RUIN] = _("BeadsOfRuin"), - [ABILITY_ORICHALCUM_PULSE] = _("OrchlcumPlse"), - [ABILITY_HADRON_ENGINE] = _("HadronEngine"), - [ABILITY_OPPORTUNIST] = _("Opportunist"), - [ABILITY_CUD_CHEW] = _("Cud Chew"), - [ABILITY_SHARPNESS] = _("Sharpness"), - [ABILITY_SUPREME_OVERLORD] = _("SuprmeOvrlrd"), - [ABILITY_COSTAR] = _("Costar"), - [ABILITY_TOXIC_DEBRIS] = _("Toxic Debris"), - [ABILITY_ARMOR_TAIL] = _("Armor Tail"), - [ABILITY_EARTH_EATER] = _("Earth Eater"), - [ABILITY_MYCELIUM_MIGHT] = _("MceliumMight"), - [ABILITY_HOSPITALITY] = _("Hospitality"), - [ABILITY_MINDS_EYE] = _("Mind's Eye"), - [ABILITY_EMBODY_ASPECT_TEAL] = _("EmbodyAspect"), - [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = _("EmbodyAspect"), - [ABILITY_EMBODY_ASPECT_WELLSPRING] = _("EmbodyAspect"), - [ABILITY_EMBODY_ASPECT_CORNERSTONE] = _("EmbodyAspect"), - [ABILITY_TOXIC_CHAIN] = _("Toxic Chain"), - [ABILITY_SUPERSWEET_SYRUP] = _("SuprswtSyrup"), -}; -#endif - -const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT] = -{ - [ABILITY_NONE] = sNoneDescription, - [ABILITY_STENCH] = sStenchDescription, - [ABILITY_DRIZZLE] = sDrizzleDescription, - [ABILITY_SPEED_BOOST] = sSpeedBoostDescription, - [ABILITY_BATTLE_ARMOR] = sBattleArmorDescription, - [ABILITY_STURDY] = sSturdyDescription, - [ABILITY_DAMP] = sDampDescription, - [ABILITY_LIMBER] = sLimberDescription, - [ABILITY_SAND_VEIL] = sSandVeilDescription, - [ABILITY_STATIC] = sStaticDescription, - [ABILITY_VOLT_ABSORB] = sVoltAbsorbDescription, - [ABILITY_WATER_ABSORB] = sWaterAbsorbDescription, - [ABILITY_OBLIVIOUS] = sObliviousDescription, - [ABILITY_CLOUD_NINE] = sCloudNineDescription, - [ABILITY_COMPOUND_EYES] = sCompoundEyesDescription, - [ABILITY_INSOMNIA] = sInsomniaDescription, - [ABILITY_COLOR_CHANGE] = sColorChangeDescription, - [ABILITY_IMMUNITY] = sImmunityDescription, - [ABILITY_FLASH_FIRE] = sFlashFireDescription, - [ABILITY_SHIELD_DUST] = sShieldDustDescription, - [ABILITY_OWN_TEMPO] = sOwnTempoDescription, - [ABILITY_SUCTION_CUPS] = sSuctionCupsDescription, - [ABILITY_INTIMIDATE] = sIntimidateDescription, - [ABILITY_SHADOW_TAG] = sShadowTagDescription, - [ABILITY_ROUGH_SKIN] = sRoughSkinDescription, - [ABILITY_WONDER_GUARD] = sWonderGuardDescription, - [ABILITY_LEVITATE] = sLevitateDescription, - [ABILITY_EFFECT_SPORE] = sEffectSporeDescription, - [ABILITY_SYNCHRONIZE] = sSynchronizeDescription, - [ABILITY_CLEAR_BODY] = sClearBodyDescription, - [ABILITY_NATURAL_CURE] = sNaturalCureDescription, - [ABILITY_LIGHTNING_ROD] = sLightningRodDescription, - [ABILITY_SERENE_GRACE] = sSereneGraceDescription, - [ABILITY_SWIFT_SWIM] = sSwiftSwimDescription, - [ABILITY_CHLOROPHYLL] = sChlorophyllDescription, - [ABILITY_ILLUMINATE] = sIlluminateDescription, - [ABILITY_TRACE] = sTraceDescription, - [ABILITY_HUGE_POWER] = sHugePowerDescription, - [ABILITY_POISON_POINT] = sPoisonPointDescription, - [ABILITY_INNER_FOCUS] = sInnerFocusDescription, - [ABILITY_MAGMA_ARMOR] = sMagmaArmorDescription, - [ABILITY_WATER_VEIL] = sWaterVeilDescription, - [ABILITY_MAGNET_PULL] = sMagnetPullDescription, - [ABILITY_SOUNDPROOF] = sSoundproofDescription, - [ABILITY_RAIN_DISH] = sRainDishDescription, - [ABILITY_SAND_STREAM] = sSandStreamDescription, - [ABILITY_PRESSURE] = sPressureDescription, - [ABILITY_THICK_FAT] = sThickFatDescription, - [ABILITY_EARLY_BIRD] = sEarlyBirdDescription, - [ABILITY_FLAME_BODY] = sFlameBodyDescription, - [ABILITY_RUN_AWAY] = sRunAwayDescription, - [ABILITY_KEEN_EYE] = sKeenEyeDescription, - [ABILITY_HYPER_CUTTER] = sHyperCutterDescription, - [ABILITY_PICKUP] = sPickupDescription, - [ABILITY_TRUANT] = sTruantDescription, - [ABILITY_HUSTLE] = sHustleDescription, - [ABILITY_CUTE_CHARM] = sCuteCharmDescription, - [ABILITY_PLUS] = sPlusDescription, - [ABILITY_MINUS] = sMinusDescription, - [ABILITY_FORECAST] = sForecastDescription, - [ABILITY_STICKY_HOLD] = sStickyHoldDescription, - [ABILITY_SHED_SKIN] = sShedSkinDescription, - [ABILITY_GUTS] = sGutsDescription, - [ABILITY_MARVEL_SCALE] = sMarvelScaleDescription, - [ABILITY_LIQUID_OOZE] = sLiquidOozeDescription, - [ABILITY_OVERGROW] = sOvergrowDescription, - [ABILITY_BLAZE] = sBlazeDescription, - [ABILITY_TORRENT] = sTorrentDescription, - [ABILITY_SWARM] = sSwarmDescription, - [ABILITY_ROCK_HEAD] = sRockHeadDescription, - [ABILITY_DROUGHT] = sDroughtDescription, - [ABILITY_ARENA_TRAP] = sArenaTrapDescription, - [ABILITY_VITAL_SPIRIT] = sVitalSpiritDescription, - [ABILITY_WHITE_SMOKE] = sWhiteSmokeDescription, - [ABILITY_PURE_POWER] = sPurePowerDescription, - [ABILITY_SHELL_ARMOR] = sShellArmorDescription, - [ABILITY_AIR_LOCK] = sAirLockDescription, - [ABILITY_TANGLED_FEET] = sTangledFeetDescription, - [ABILITY_MOTOR_DRIVE] = sMotorDriveDescription, - [ABILITY_RIVALRY] = sRivalryDescription, - [ABILITY_STEADFAST] = sSteadfastDescription, - [ABILITY_SNOW_CLOAK] = sSnowCloakDescription, - [ABILITY_GLUTTONY] = sGluttonyDescription, - [ABILITY_ANGER_POINT] = sAngerPointDescription, - [ABILITY_UNBURDEN] = sUnburdenDescription, - [ABILITY_HEATPROOF] = sHeatproofDescription, - [ABILITY_SIMPLE] = sSimpleDescription, - [ABILITY_DRY_SKIN] = sDrySkinDescription, - [ABILITY_DOWNLOAD] = sDownloadDescription, - [ABILITY_IRON_FIST] = sIronFistDescription, - [ABILITY_POISON_HEAL] = sPoisonHealDescription, - [ABILITY_ADAPTABILITY] = sAdaptabilityDescription, - [ABILITY_SKILL_LINK] = sSkillLinkDescription, - [ABILITY_HYDRATION] = sHydrationDescription, - [ABILITY_SOLAR_POWER] = sSolarPowerDescription, - [ABILITY_QUICK_FEET] = sQuickFeetDescription, - [ABILITY_NORMALIZE] = sNormalizeDescription, - [ABILITY_SNIPER] = sSniperDescription, - [ABILITY_MAGIC_GUARD] = sMagicGuardDescription, - [ABILITY_NO_GUARD] = sNoGuardDescription, - [ABILITY_STALL] = sStallDescription, - [ABILITY_TECHNICIAN] = sTechnicianDescription, - [ABILITY_LEAF_GUARD] = sLeafGuardDescription, - [ABILITY_KLUTZ] = sKlutzDescription, - [ABILITY_MOLD_BREAKER] = sMoldBreakerDescription, - [ABILITY_SUPER_LUCK] = sSuperLuckDescription, - [ABILITY_AFTERMATH] = sAftermathDescription, - [ABILITY_ANTICIPATION] = sAnticipationDescription, - [ABILITY_FOREWARN] = sForewarnDescription, - [ABILITY_UNAWARE] = sUnawareDescription, - [ABILITY_TINTED_LENS] = sTintedLensDescription, - [ABILITY_FILTER] = sFilterDescription, - [ABILITY_SLOW_START] = sSlowStartDescription, - [ABILITY_SCRAPPY] = sScrappyDescription, - [ABILITY_STORM_DRAIN] = sStormDrainDescription, - [ABILITY_ICE_BODY] = sIceBodyDescription, - [ABILITY_SOLID_ROCK] = sFilterDescription, - [ABILITY_SNOW_WARNING] = sSnowWarningDescription, - [ABILITY_HONEY_GATHER] = sHoneyGatherDescription, - [ABILITY_FRISK] = sFriskDescription, - [ABILITY_RECKLESS] = sRecklessDescription, - [ABILITY_MULTITYPE] = sMultitypeDescription, - [ABILITY_FLOWER_GIFT] = sFlowerGiftDescription, - [ABILITY_BAD_DREAMS] = sBadDreamsDescription, - [ABILITY_PICKPOCKET] = sPickpocketDescription, - [ABILITY_SHEER_FORCE] = sSheerForceDescription, - [ABILITY_CONTRARY] = sContraryDescription, - [ABILITY_UNNERVE] = sUnnerveDescription, - [ABILITY_DEFIANT] = sDefiantDescription, - [ABILITY_DEFEATIST] = sDefeatistDescription, - [ABILITY_CURSED_BODY] = sCursedBodyDescription, - [ABILITY_HEALER] = sHealerDescription, - [ABILITY_FRIEND_GUARD] = sFriendGuardDescription, - [ABILITY_WEAK_ARMOR] = sWeakArmorDescription, - [ABILITY_HEAVY_METAL] = sHeavyMetalDescription, - [ABILITY_LIGHT_METAL] = sLightMetalDescription, - [ABILITY_MULTISCALE] = sMultiscaleDescription, - [ABILITY_TOXIC_BOOST] = sToxicBoostDescription, - [ABILITY_FLARE_BOOST] = sFlareBoostDescription, - [ABILITY_HARVEST] = sHarvestDescription, - [ABILITY_TELEPATHY] = sTelepathyDescription, - [ABILITY_MOODY] = sMoodyDescription, - [ABILITY_OVERCOAT] = sOvercoatDescription, - [ABILITY_POISON_TOUCH] = sPoisonPointDescription, - [ABILITY_REGENERATOR] = sNaturalCureDescription, - [ABILITY_BIG_PECKS] = sBigPecksDescription, - [ABILITY_SAND_RUSH] = sSandRushDescription, - [ABILITY_WONDER_SKIN] = sWonderSkinDescription, - [ABILITY_ANALYTIC] = sAnalyticDescription, - [ABILITY_ILLUSION] = sIllusionDescription, - [ABILITY_IMPOSTER] = sImposterDescription, - [ABILITY_INFILTRATOR] = sInfiltratorDescription, - [ABILITY_MUMMY] = sMummyDescription, - [ABILITY_MOXIE] = sMoxieDescription, - [ABILITY_JUSTIFIED] = sJustifiedDescription, - [ABILITY_RATTLED] = sRattledDescription, - [ABILITY_MAGIC_BOUNCE] = sMagicBounceDescription, - [ABILITY_SAP_SIPPER] = sSapSipperDescription, - [ABILITY_PRANKSTER] = sPranksterDescription, - [ABILITY_SAND_FORCE] = sSandForceDescription, - [ABILITY_IRON_BARBS] = sRoughSkinDescription, - [ABILITY_ZEN_MODE] = sZenModeDescription, - [ABILITY_VICTORY_STAR] = sVictoryStarDescription, - [ABILITY_TURBOBLAZE] = sMoldBreakerDescription, - [ABILITY_TERAVOLT] = sMoldBreakerDescription, - [ABILITY_AROMA_VEIL] = sAromaVeilDescription, - [ABILITY_FLOWER_VEIL] = sFlowerVeilDescription, - [ABILITY_CHEEK_POUCH] = sCheekPouchDescription, - [ABILITY_PROTEAN] = sProteanDescription, - [ABILITY_FUR_COAT] = sFurCoatDescription, - [ABILITY_MAGICIAN] = sPickpocketDescription, - [ABILITY_BULLETPROOF] = sBulletproofDescription, - [ABILITY_COMPETITIVE] = sCompetitiveDescription, - [ABILITY_STRONG_JAW] = sStrongJawDescription, - [ABILITY_REFRIGERATE] = sRefrigerateDescription, - [ABILITY_SWEET_VEIL] = sSweetVeilDescription, - [ABILITY_STANCE_CHANGE] = sStanceChangeDescription, - [ABILITY_GALE_WINGS] = sGaleWingsDescription, - [ABILITY_MEGA_LAUNCHER] = sMegaLauncherDescription, - [ABILITY_GRASS_PELT] = sGrassPeltDescription, - [ABILITY_SYMBIOSIS] = sSymbiosisDescription, - [ABILITY_TOUGH_CLAWS] = sToughClawsDescription, - [ABILITY_PIXILATE] = sPixilateDescription, - [ABILITY_GOOEY] = sGooeyDescription, - [ABILITY_AERILATE] = sAerilateDescription, - [ABILITY_PARENTAL_BOND] = sParentalBondDescription, - [ABILITY_DARK_AURA] = sDarkAuraDescription, - [ABILITY_FAIRY_AURA] = sFairyAuraDescription, - [ABILITY_AURA_BREAK] = sAuraBreakDescription, - [ABILITY_PRIMORDIAL_SEA] = sPrimordialSeaDescription, - [ABILITY_DESOLATE_LAND] = sDesolateLandDescription, - [ABILITY_DELTA_STREAM] = sDeltaStreamDescription, - [ABILITY_STAMINA] = sStaminaDescription, - [ABILITY_WIMP_OUT] = sWimpOutDescription, - [ABILITY_EMERGENCY_EXIT] = sWimpOutDescription, - [ABILITY_WATER_COMPACTION] = sWaterCompactionDescription, - [ABILITY_MERCILESS] = sMercilessDescription, - [ABILITY_SHIELDS_DOWN] = sShieldsDownDescription, - [ABILITY_STAKEOUT] = sStakeoutDescription, - [ABILITY_WATER_BUBBLE] = sWaterBubbleDescription, - [ABILITY_STEELWORKER] = sSteelworkerDescription, - [ABILITY_BERSERK] = sBerserkDescription, - [ABILITY_SLUSH_RUSH] = sSlushRushDescription, - [ABILITY_LONG_REACH] = sLongReachDescription, - [ABILITY_LIQUID_VOICE] = sLiquidVoiceDescription, - [ABILITY_TRIAGE] = sTriageDescription, - [ABILITY_GALVANIZE] = sGalvanizeDescription, - [ABILITY_SURGE_SURFER] = sSurgeSurferDescription, - [ABILITY_SCHOOLING] = sSchoolingDescription, - [ABILITY_DISGUISE] = sDisguiseDescription, - [ABILITY_BATTLE_BOND] = sBattleBondDescription, - [ABILITY_POWER_CONSTRUCT] = sPowerConstructDescription, - [ABILITY_CORROSION] = sCorrosionDescription, - [ABILITY_COMATOSE] = sComatoseDescription, - [ABILITY_QUEENLY_MAJESTY] = sQueenlyMajestyDescription, - [ABILITY_INNARDS_OUT] = sInnardsOutDescription, - [ABILITY_DANCER] = sDancerDescription, - [ABILITY_BATTERY] = sBatteryDescription, - [ABILITY_FLUFFY] = sFluffyDescription, - [ABILITY_DAZZLING] = sQueenlyMajestyDescription, - [ABILITY_SOUL_HEART] = sSoulHeartDescription, - [ABILITY_TANGLING_HAIR] = sGooeyDescription, - [ABILITY_RECEIVER] = sReceiverDescription, - [ABILITY_POWER_OF_ALCHEMY] = sReceiverDescription, - [ABILITY_BEAST_BOOST] = sBeastBoostDescription, - [ABILITY_RKS_SYSTEM] = sRKSSystemDescription, - [ABILITY_ELECTRIC_SURGE] = sElectricSurgeDescription, - [ABILITY_PSYCHIC_SURGE] = sPsychicSurgeDescription, - [ABILITY_MISTY_SURGE] = sMistySurgeDescription, - [ABILITY_GRASSY_SURGE] = sGrassySurgeDescription, - [ABILITY_FULL_METAL_BODY] = sFullMetalBodyDescription, - [ABILITY_SHADOW_SHIELD] = sMultiscaleDescription, - [ABILITY_PRISM_ARMOR] = sFilterDescription, - [ABILITY_NEUROFORCE] = sNeuroforceDescription, - [ABILITY_INTREPID_SWORD] = sIntrepidSwordDescription, - [ABILITY_DAUNTLESS_SHIELD] = sDauntlessShieldDescription, - [ABILITY_LIBERO] = sLiberoDescription, - [ABILITY_BALL_FETCH] = sBallFetchDescription, - [ABILITY_COTTON_DOWN] = sCottonDownDescription, - [ABILITY_PROPELLER_TAIL] = sPropellerTailDescription, - [ABILITY_MIRROR_ARMOR] = sMirrorArmorDescription, - [ABILITY_GULP_MISSILE] = sGulpMissileDescription, - [ABILITY_STALWART] = sStalwartDescription, - [ABILITY_STEAM_ENGINE] = sSteamEngineDescription, - [ABILITY_PUNK_ROCK] = sPunkRockDescription, - [ABILITY_SAND_SPIT] = sSandSpitDescription, - [ABILITY_ICE_SCALES] = sIceScalesDescription, - [ABILITY_RIPEN] = sRipenDescription, - [ABILITY_ICE_FACE] = sIceFaceDescription, - [ABILITY_POWER_SPOT] = sPowerSpotDescription, - [ABILITY_MIMICRY] = sMimicryDescription, - [ABILITY_SCREEN_CLEANER] = sScreenCleanerDescription, - [ABILITY_STEELY_SPIRIT] = sSteelySpiritDescription, - [ABILITY_PERISH_BODY] = sPerishBodyDescription, - [ABILITY_WANDERING_SPIRIT] = sWanderingSpiritDescription, - [ABILITY_GORILLA_TACTICS] = sGorillaTacticsDescription, - [ABILITY_NEUTRALIZING_GAS] = sNeutralizingGasDescription, - [ABILITY_PASTEL_VEIL] = sPastelVeilDescription, - [ABILITY_HUNGER_SWITCH] = sHungerSwitchDescription, - [ABILITY_QUICK_DRAW] = sQuickDrawDescription, - [ABILITY_UNSEEN_FIST] = sUnseenFistDescription, - [ABILITY_CURIOUS_MEDICINE] = sCuriousMedicineDescription, - [ABILITY_TRANSISTOR] = sTransistorDescription, - [ABILITY_DRAGONS_MAW] = sDragonsMawDescription, - [ABILITY_CHILLING_NEIGH] = sChillingNeighDescription, - [ABILITY_GRIM_NEIGH] = sGrimNeighDescription, - [ABILITY_AS_ONE_ICE_RIDER] = sAsOneIceRiderDescription, - [ABILITY_AS_ONE_SHADOW_RIDER] = sAsOneShadowRiderDescription, - [ABILITY_LINGERING_AROMA] = sLingeringAromaDescription, - [ABILITY_SEED_SOWER] = sSeedSowerDescription, - [ABILITY_THERMAL_EXCHANGE] = sThermalExchangeDescription, - [ABILITY_ANGER_SHELL] = sAngerShellDescription, - [ABILITY_PURIFYING_SALT] = sPurifyingSaltDescription, - [ABILITY_WELL_BAKED_BODY] = sWellBakedBodyDescription, - [ABILITY_WIND_RIDER] = sWindRiderDescription, - [ABILITY_GUARD_DOG] = sGuardDogDescription, - [ABILITY_ROCKY_PAYLOAD] = sRockyPayloadDescription, - [ABILITY_WIND_POWER] = sWindPowerDescription, - [ABILITY_ZERO_TO_HERO] = sZeroToHeroDescription, - [ABILITY_COMMANDER] = sCommanderDescription, - [ABILITY_ELECTROMORPHOSIS] = sElectromorphosisDescription, - [ABILITY_PROTOSYNTHESIS] = sProtosynthesisDescription, - [ABILITY_QUARK_DRIVE] = sQuarkDriveDescription, - [ABILITY_GOOD_AS_GOLD] = sGoodAsGoldDescription, - [ABILITY_VESSEL_OF_RUIN] = sVesselOfRuinDescription, - [ABILITY_SWORD_OF_RUIN] = sSwordOfRuinDescription, - [ABILITY_TABLETS_OF_RUIN] = sTabletsOfRuinDescription, - [ABILITY_BEADS_OF_RUIN] = sBeadsOfRuinDescription, - [ABILITY_ORICHALCUM_PULSE] = sOrichalcumPulseDescription, - [ABILITY_HADRON_ENGINE] = sHadronEngineDescription, - [ABILITY_OPPORTUNIST] = sOpportunistDescription, - [ABILITY_CUD_CHEW] = sCudChewDescription, - [ABILITY_SHARPNESS] = sSharpnessDescription, - [ABILITY_SUPREME_OVERLORD] = sSupremeOverlordDescription, - [ABILITY_COSTAR] = sCostarDescription, - [ABILITY_TOXIC_DEBRIS] = sToxicDebrisDescription, - [ABILITY_ARMOR_TAIL] = sArmorTailDescription, - [ABILITY_EARTH_EATER] = sEarthEaterDescription, - [ABILITY_MYCELIUM_MIGHT] = sMyceliumMightDescription, - [ABILITY_HOSPITALITY] = sHospitalityDescription, - [ABILITY_MINDS_EYE] = sMindsEyeDescription, - [ABILITY_EMBODY_ASPECT_TEAL] = sEmbodyAspectTealDescription, - [ABILITY_EMBODY_ASPECT_HEARTHFLAME] = sEmbodyAspectHearthflameDescription, - [ABILITY_EMBODY_ASPECT_WELLSPRING] = sEmbodyAspectWellspringDescription, - [ABILITY_EMBODY_ASPECT_CORNERSTONE] = sEmbodyAspectCornerstoneDescription, - [ABILITY_TOXIC_CHAIN] = sToxicChainDescription, - [ABILITY_SUPERSWEET_SYRUP] = sSupersweetSyrupDescription, -}; diff --git a/src/data/text/move_descriptions.h b/src/data/text/move_descriptions.h index c321a844b1de..4aa7293036fe 100644 --- a/src/data/text/move_descriptions.h +++ b/src/data/text/move_descriptions.h @@ -3284,6 +3284,54 @@ static const u8 sIvyCudgelDescription[] = _( "Type changes with held mask.\n" "High critical-hit ratio."); +static const u8 sElectroShotDescription[] = _( + "Absorbs electricity in one turn,\n" + "then attacks next turn."); + +static const u8 sTeraStarstormDescription[] = _( + "Damages all opponents if user is\n" + "Stellar form Terapagos."); + +static const u8 sFickleBeamDescription[] = _( + "Shoots a beam of light. Sometimes\n" + "twice as strong."); + +static const u8 sBurningBulwarkDescription[] = _( + "Evades attack, and burns\n" + "the foe if struck."); + +static const u8 sTachyonCutterDescription[] = _( + "Launches particle blades at\n" + "the target. Strikes twice."); + +static const u8 sDragonCheerDescription[] = _( + "Increases allies' critical hit\n" + "ration, especially if Dragons."); + +static const u8 sAlluringVoiceDescription[] = _( + "Confuses the target if their\n" + "stats were boosted this turn."); + +static const u8 sTemperFlareDescription[] = _( + "A desperation attack. Power\n" + "doubles if last move failed."); + +static const u8 sSupercellSlamDescription[] = _( + "An electrified slam. If it\n" + "misses, the user is hurt."); + +static const u8 sPsychicNoiseDescription[] = _( + "Unpleasant sound waves that\n" + "damage and prevent healing."); + +static const u8 sUpperHandDescription[] = _( + "Makes the target flinch if\n" + "readying a priority move."); + +static const u8 sMalignantChainDescription[] = _( + "A corrosive chain attack\n" + "that may badly poison."); + const u8 gNotDoneYetDescription[] = _( "This move can't be used. Its\n" "effect is in development."); @@ -4127,4 +4175,19 @@ const u8 *const gMoveDescriptionPointers[MOVES_COUNT - 1] = [MOVE_MATCHA_GOTCHA - 1] = sMatchaGotchaDescription, [MOVE_SYRUP_BOMB - 1] = sSyrupBombDescription, [MOVE_IVY_CUDGEL - 1] = sIvyCudgelDescription, + [MOVE_ELECTRO_SHOT - 1] = sElectroShotDescription, + [MOVE_TERA_STARSTORM - 1] = sTeraStarstormDescription, + [MOVE_FICKLE_BEAM - 1] = sFickleBeamDescription, + [MOVE_BURNING_BULWARK - 1] = sBurningBulwarkDescription, + [MOVE_THUNDERCLAP - 1] = sSuckerPunchDescription, + [MOVE_MIGHTY_CLEAVE - 1] = sFeintDescription, + [MOVE_TACHYON_CUTTER - 1] = sTachyonCutterDescription, + [MOVE_HARD_PRESS - 1] = sWringOutDescription, + [MOVE_DRAGON_CHEER - 1] = sDragonCheerDescription, + [MOVE_ALLURING_VOICE - 1] = sAlluringVoiceDescription, + [MOVE_TEMPER_FLARE - 1] = sTemperFlareDescription, + [MOVE_SUPERCELL_SLAM - 1] = sSupercellSlamDescription, + [MOVE_PSYCHIC_NOISE - 1] = sPsychicNoiseDescription, + [MOVE_UPPER_HAND - 1] = sUpperHandDescription, + [MOVE_MALIGNANT_CHAIN - 1] = sMalignantChainDescription, }; diff --git a/src/data/text/move_names.h b/src/data/text/move_names.h index 01d613751efc..f69b1f96a74f 100644 --- a/src/data/text/move_names.h +++ b/src/data/text/move_names.h @@ -835,6 +835,21 @@ const u8 gMoveNames[MOVES_COUNT_DYNAMAX][MOVE_NAME_LENGTH + 1] = [MOVE_MATCHA_GOTCHA] = _("Matcha Gotcha"), [MOVE_SYRUP_BOMB] = _("Syrup Bomb"), [MOVE_IVY_CUDGEL] = _("Ivy Cudgel"), + [MOVE_ELECTRO_SHOT] = _("Electro Shot"), + [MOVE_TERA_STARSTORM] = _("Tera Starstorm"), + [MOVE_FICKLE_BEAM] = _("Fickle Beam"), + [MOVE_BURNING_BULWARK] = _("Burning Bulwark"), + [MOVE_THUNDERCLAP] = _("Thunderclap"), + [MOVE_MIGHTY_CLEAVE] = _("Mighty Cleave"), + [MOVE_TACHYON_CUTTER] = _("Tachyon Cutter"), + [MOVE_HARD_PRESS] = _("Hard Press"), + [MOVE_DRAGON_CHEER] = _("Dragon Cheer"), + [MOVE_ALLURING_VOICE] = _("Alluring Voice"), + [MOVE_TEMPER_FLARE] = _("Temper Flare"), + [MOVE_SUPERCELL_SLAM] = _("Supercell Slam"), + [MOVE_PSYCHIC_NOISE] = _("Psychic Noise"), + [MOVE_UPPER_HAND] = _("Upper Hand"), + [MOVE_MALIGNANT_CHAIN] = _("Malignant Chain"), // Max Moves [MOVE_MAX_GUARD] = _("Max Guard"), [MOVE_MAX_STRIKE] = _("Max Strike"), @@ -1727,6 +1742,21 @@ const u8 gMoveNames[MOVES_COUNT_DYNAMAX][MOVE_NAME_LENGTH + 1] = [MOVE_MATCHA_GOTCHA] = _("MatchaGotcha"), [MOVE_SYRUP_BOMB] = _("Syrup Bomb"), [MOVE_IVY_CUDGEL] = _("Ivy Cudgel"), + [MOVE_ELECTRO_SHOT] = _("Electro Shot"), + [MOVE_TERA_STARSTORM] = _("TeraStarstrm"), + [MOVE_FICKLE_BEAM] = _("Fickle Beam"), + [MOVE_BURNING_BULWARK] = _("BurnngBulwrk"), + [MOVE_THUNDERCLAP] = _("Thunderclap"), + [MOVE_MIGHTY_CLEAVE] = _("MightyCleave"), + [MOVE_TACHYON_CUTTER] = _("TachyonCuttr"), + [MOVE_HARD_PRESS] = _("Hard Press"), + [MOVE_DRAGON_CHEER] = _("Dragon Cheer"), + [MOVE_ALLURING_VOICE] = _("AllurngVoice"), + [MOVE_TEMPER_FLARE] = _("Temper Flare"), + [MOVE_SUPERCELL_SLAM] = _("SuprcellSlam"), + [MOVE_PSYCHIC_NOISE] = _("PsychicNoise"), + [MOVE_UPPER_HAND] = _("Upper Hand"), + [MOVE_MALIGNANT_CHAIN] = _("MalignntChan"), // Max Moves [MOVE_MAX_GUARD] = _("M-Guard"), [MOVE_MAX_STRIKE] = _("M-Strike"), diff --git a/src/daycare.c b/src/daycare.c index 33b3d8ac1b8a..e8426b4c0062 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -229,7 +229,6 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar } daycareMon->mon = mon->box; - BoxMonRestorePP(&daycareMon->mon); daycareMon->steps = 0; ZeroMonData(mon); CompactPartySlots(); @@ -251,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) { @@ -739,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 c1853af4cf27..46655625b891 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1437,6 +1437,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 @@ -1446,8 +1447,6 @@ static void DebugTask_HandleMenuInput_FlagsVars(u8 taskId) RemoveWindow(gTasks[taskId].tSubWindowId); Free(sDebugMenuListData); } - else - Debug_RedrawListMenu(taskId); } } else if (JOY_NEW(B_BUTTON)) @@ -2938,7 +2937,7 @@ static void ResetMonDataStruct(struct DebugMonData *sDebugMonData) { sDebugMonData->species = 1; sDebugMonData->level = MIN_LEVEL; - sDebugMonData->isShiny = 0; + sDebugMonData->isShiny = FALSE; sDebugMonData->nature = 0; sDebugMonData->abilityNum = 0; sDebugMonData->mon_iv_hp = 0; @@ -3264,7 +3263,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId) ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2); StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15); abilityId = GetAbilityBySpecies(sDebugMonData->species, 0); - StringCopy(gStringVar1, gAbilityNames[abilityId]); + StringCopy(gStringVar1, gAbilities[abilityId].name); StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility); AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL); @@ -3309,7 +3308,7 @@ static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId) StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]); ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2); StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15); - StringCopy(gStringVar1, gAbilityNames[abilityId]); + StringCopy(gStringVar1, gAbilities[abilityId].name); StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility); AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL); } @@ -3608,7 +3607,7 @@ static void DebugAction_Give_Pokemon_ComplexCreateMon(u8 taskId) //https://githu u8 iv_val; u16 species = sDebugMonData->species; u8 level = sDebugMonData->level; - u8 isShiny = sDebugMonData->isShiny; //Shiny: no 0, yes 1 + bool8 isShiny = sDebugMonData->isShiny; u8 nature = sDebugMonData->nature; u8 abilityNum = sDebugMonData->abilityNum; moves[0] = sDebugMonData->mon_move_0; @@ -3625,26 +3624,10 @@ static void DebugAction_Give_Pokemon_ComplexCreateMon(u8 taskId) //https://githu //Nature if (nature == NUM_NATURES || nature == 0xFF) nature = Random() % NUM_NATURES; + CreateMonWithNature(&mon, species, level, 32, nature); //Shininess - if (isShiny == 1) - { - u32 personality; - u32 otid = gSaveBlock2Ptr->playerTrainerId[0] - | (gSaveBlock2Ptr->playerTrainerId[1] << 8) - | (gSaveBlock2Ptr->playerTrainerId[2] << 16) - | (gSaveBlock2Ptr->playerTrainerId[3] << 24); - - do - { - personality = Random32(); - personality = ((((Random() % 8) ^ (HIHALF(otid) ^ LOHALF(otid))) ^ LOHALF(personality)) << 16) | LOHALF(personality); - } while (nature != GetNatureFromPersonality(personality)); - - CreateMon(&mon, species, level, 32, 1, personality, OT_ID_PRESET, otid); - } - else - CreateMonWithNature(&mon, species, level, 32, nature); + SetMonData(&mon, MON_DATA_IS_SHINY, &isShiny); //IVs for (i = 0; i < NUM_STATS; i++) diff --git a/src/evolution_scene.c b/src/evolution_scene.c index 1bd0e2656154..b254dab42ac7 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -209,7 +209,8 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u { u8 name[POKEMON_NAME_BUFFER_SIZE]; u16 currSpecies; - u32 trainerId, personality; + u32 personality; + bool32 isShiny; u8 id; SetHBlankCallback(NULL); @@ -255,13 +256,13 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u // preEvo sprite currSpecies = GetMonData(mon, MON_DATA_SPECIES); - trainerId = GetMonData(mon, MON_DATA_OT_ID); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); personality = GetMonData(mon, MON_DATA_PERSONALITY); LoadSpecialPokePic(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], currSpecies, personality, TRUE); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(currSpecies, trainerId, personality), OBJ_PLTT_ID(1), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(currSpecies, isShiny, personality), OBJ_PLTT_ID(1), PLTT_SIZE_4BPP); SetMultiuseSpriteTemplateToPokemon(currSpecies, B_POSITION_OPPONENT_LEFT); gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; @@ -276,7 +277,7 @@ void EvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, bool8 canStopEvo, u postEvoSpecies, personality, TRUE); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_RIGHT); gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; @@ -310,11 +311,12 @@ static void CB2_EvolutionSceneLoadGraphics(void) { u8 id; u16 postEvoSpecies; - u32 trainerId, personality; + u32 personality; struct Pokemon *mon = &gPlayerParty[gTasks[sEvoStructPtr->evoTaskId].tPartyId]; + bool8 isShiny; postEvoSpecies = gTasks[sEvoStructPtr->evoTaskId].tPostEvoSpecies; - trainerId = GetMonData(mon, MON_DATA_OT_ID); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); personality = GetMonData(mon, MON_DATA_PERSONALITY); SetHBlankCallback(NULL); @@ -352,7 +354,7 @@ static void CB2_EvolutionSceneLoadGraphics(void) postEvoSpecies, personality, TRUE); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_RIGHT); gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; @@ -416,13 +418,13 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void) break; case 4: { - u32 trainerId = GetMonData(mon, MON_DATA_OT_ID); + bool8 isShiny = GetMonData(mon, MON_DATA_IS_SHINY); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY); LoadSpecialPokePic(gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], postEvoSpecies, personality, TRUE); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); gMain.state++; } break; @@ -464,8 +466,9 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit { u8 name[POKEMON_NAME_BUFFER_SIZE]; u16 currSpecies; - u32 trainerId, personality; + u32 personality; u8 id; + bool8 isShiny; GetMonData(mon, MON_DATA_NICKNAME, name); StringCopy_Nickname(gStringVar1, name); @@ -476,7 +479,7 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit // preEvo sprite currSpecies = GetMonData(mon, MON_DATA_SPECIES); personality = GetMonData(mon, MON_DATA_PERSONALITY); - trainerId = GetMonData(mon, MON_DATA_OT_ID); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); sEvoStructPtr = AllocZeroed(sizeof(struct EvoInfo)); sEvoStructPtr->preEvoSpriteId = preEvoSpriteId; @@ -486,7 +489,7 @@ void TradeEvolutionScene(struct Pokemon *mon, u16 postEvoSpecies, u8 preEvoSprit personality, TRUE); - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, trainerId, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(postEvoSpecies, isShiny, personality), OBJ_PLTT_ID(2), PLTT_SIZE_4BPP); SetMultiuseSpriteTemplateToPokemon(postEvoSpecies, B_POSITION_OPPONENT_LEFT); gMultiuseSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; @@ -564,8 +567,6 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon) SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_NICKNAME, GetSpeciesName(evolutions[1].targetSpecies)); SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_HELD_ITEM, &data); SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MARKINGS, &data); - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_ENCRYPT_SEPARATOR, &data); - #if P_SHEDINJA_BALL >= GEN_4 SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_POKEBALL, &ball); RemoveBagItem(ball, 1); @@ -573,7 +574,7 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon) for (i = MON_DATA_COOL_RIBBON; i < MON_DATA_COOL_RIBBON + CONTEST_CATEGORIES_COUNT; i++) SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data); - for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_UNUSED_RIBBONS; i++) + for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_WORLD_RIBBON; i++) SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data); SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_STATUS, &data); diff --git a/src/field_effect.c b/src/field_effect.c index 5d0ba3a50d6e..8309e10b8e2f 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -183,7 +183,7 @@ static void AnimateIndoorShowMonBg(struct Task *); static bool8 SlideIndoorBannerOnscreen(struct Task *); static bool8 SlideIndoorBannerOffscreen(struct Task *); -static u8 InitFieldMoveMonSprite(u32, u32, u32); +static u8 InitFieldMoveMonSprite(u32, bool8, u32); static void SpriteCB_FieldMoveMonSlideOnscreen(struct Sprite *); static void SpriteCB_FieldMoveMonWaitAfterCry(struct Sprite *); static void SpriteCB_FieldMoveMonSlideOffscreen(struct Sprite *); @@ -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"); @@ -919,7 +919,7 @@ u8 AddNewGameBirchObject(s16 x, s16 y, u8 subpriority) u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority) { - s32 spriteId = CreateMonPicSprite(species, 0, 0x8000, TRUE, x, y, 0, species); + s32 spriteId = CreateMonPicSprite(species, FALSE, 0x8000, TRUE, x, y, 0, species); PreservePaletteInWeather(IndexOfSpritePaletteTag(species) + 0x10); if (spriteId == 0xFFFF) return MAX_SPRITES; @@ -927,10 +927,10 @@ u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority) return spriteId; } -u8 CreateMonSprite_FieldMove(u16 species, u32 otId, u32 personality, s16 x, s16 y, u8 subpriority) +u8 CreateMonSprite_FieldMove(u16 species, bool8 isShiny, u32 personality, s16 x, s16 y, u8 subpriority) { - u16 spriteId = CreateMonPicSprite(species, otId, personality, TRUE, x, y, 0, species); - PreservePaletteInWeather(IndexOfSpritePaletteTag(species) + 0x10); + u16 spriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, x, y, 0, species); + PreservePaletteInWeather(gSprites[spriteId].oam.paletteNum + 0x10); if (spriteId == 0xFFFF) return MAX_SPRITES; else @@ -2586,7 +2586,7 @@ bool8 FldEff_FieldMoveShowMonInit(void) bool32 noDucking = gFieldEffectArguments[0] & SHOW_MON_CRY_NO_DUCKING; pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]]; gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES); - gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID); + gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_IS_SHINY); gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY); gFieldEffectArguments[0] |= noDucking; FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON); @@ -2926,14 +2926,14 @@ static bool8 SlideIndoorBannerOffscreen(struct Task *task) #undef tBgOffset #undef tMonSpriteId -static u8 InitFieldMoveMonSprite(u32 species, u32 otId, u32 personality) +static u8 InitFieldMoveMonSprite(u32 species, bool8 isShiny, u32 personality) { bool16 noDucking; u8 monSprite; struct Sprite *sprite; noDucking = (species & SHOW_MON_CRY_NO_DUCKING) >> 16; species &= ~SHOW_MON_CRY_NO_DUCKING; - monSprite = CreateMonSprite_FieldMove(species, otId, personality, 320, 80, 0); + monSprite = CreateMonSprite_FieldMove(species, isShiny, personality, 320, 80, 0); sprite = &gSprites[monSprite]; sprite->callback = SpriteCallbackDummy; sprite->oam.priority = 0; 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 40bc24c74167..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]; @@ -2462,10 +2462,7 @@ void CreateFrontierBrainPokemon(void) do { - do - { - j = Random32(); //should just be one while loop, but that doesn't match - } while (IsShinyOtIdPersonality(FRONTIER_BRAIN_OTID, j)); + j = Random32(); //should just be one while loop, but that doesn't match } while (sFrontierBrainsMons[facility][symbol][i].nature != GetNatureFromPersonality(j)); CreateMon(&gEnemyParty[monPartyId], sFrontierBrainsMons[facility][symbol][i].species, @@ -2484,6 +2481,8 @@ void CreateFrontierBrainPokemon(void) friendship = 0; } SetMonData(&gEnemyParty[monPartyId], MON_DATA_FRIENDSHIP, &friendship); + j = FALSE; + SetMonData(&gPlayerParty[MULTI_PARTY_SIZE + i], MON_DATA_IS_SHINY, &j); CalculateMonStats(&gEnemyParty[monPartyId]); monPartyId++; } 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 caa497e39551..f7a5d2c37899 100644 --- a/src/hall_of_fame.c +++ b/src/hall_of_fame.c @@ -42,7 +42,8 @@ struct HallofFameMon { u32 tid; u32 personality; - u16 species; + u16 isShiny:1; + u16 species:15; u8 lvl; u8 nickname[POKEMON_NAME_LENGTH]; }; @@ -336,6 +337,7 @@ static const struct HallofFameMon sDummyFameMon = { .tid = 0x3EA03EA, .personality = 0, + .isShiny = FALSE, .species = SPECIES_NONE, .lvl = 0, .nickname = {0} @@ -447,6 +449,7 @@ static void Task_Hof_InitMonData(u8 taskId) { sHofMonPtr->mon[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG); sHofMonPtr->mon[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID); + sHofMonPtr->mon[i].isShiny = GetMonData(&gPlayerParty[i], MON_DATA_IS_SHINY); sHofMonPtr->mon[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); sHofMonPtr->mon[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nickname); @@ -458,6 +461,7 @@ static void Task_Hof_InitMonData(u8 taskId) { sHofMonPtr->mon[i].species = SPECIES_NONE; sHofMonPtr->mon[i].tid = 0; + sHofMonPtr->mon[i].isShiny = FALSE; sHofMonPtr->mon[i].personality = 0; sHofMonPtr->mon[i].lvl = 0; sHofMonPtr->mon[i].nickname[0] = EOS; @@ -583,7 +587,7 @@ static void Task_Hof_DisplayMon(u8 taskId) if (currMon->species == SPECIES_EGG) destY += 10; - spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->tid, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE); + spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->isShiny, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE); gSprites[spriteId].tDestinationX = destX; gSprites[spriteId].tDestinationY = destY; gSprites[spriteId].data[0] = 0; @@ -621,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)); @@ -929,7 +933,7 @@ static void Task_HofPC_DrawSpritesPrintText(u8 taskId) if (currMon->species == SPECIES_EGG) posY += 10; - spriteId = CreateMonPicSprite(currMon->species, currMon->tid, currMon->personality, TRUE, posX, posY, i, TAG_NONE); + spriteId = CreateMonPicSprite(currMon->species, currMon->isShiny, currMon->personality, TRUE, posX, posY, i, TAG_NONE); gSprites[spriteId].oam.priority = 1; gTasks[taskId].tMonSpriteId(i) = spriteId; } diff --git a/src/item.c b/src/item.c index 52af1c5f0bbd..e751624747de 100644 --- a/src/item.c +++ b/src/item.c @@ -878,7 +878,7 @@ const u8 *ItemId_GetName(u16 itemId) return gItems[SanitizeItemId(itemId)].name; } -u16 ItemId_GetPrice(u16 itemId) +u32 ItemId_GetPrice(u16 itemId) { return gItems[SanitizeItemId(itemId)].price; } diff --git a/src/item_use.c b/src/item_use.c index bce5d83ed62d..b16169a9ba78 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -58,6 +58,7 @@ static u8 GetDirectionToHiddenItem(s16, s16); static void PlayerFaceHiddenItem(u8); static void CheckForHiddenItemsInMapConnection(u8); static void Task_OpenRegisteredPokeblockCase(u8); +static void Task_AccessPokemonBoxLink(u8); static void ItemUseOnFieldCB_Bike(u8); static void ItemUseOnFieldCB_Rod(u8); static void ItemUseOnFieldCB_Itemfinder(u8); @@ -680,6 +681,18 @@ static void Task_OpenRegisteredPokeblockCase(u8 taskId) } } +void ItemUseOutOfBattle_PokemonBoxLink(u8 taskId) +{ + sItemUseOnFieldCB = Task_AccessPokemonBoxLink; + SetUpItemUseOnFieldCallback(taskId); +} + +static void Task_AccessPokemonBoxLink(u8 taskId) +{ + ScriptContext_SetupScript(EventScript_AccessPokemonBoxLink); + DestroyTask(taskId); +} + void ItemUseOutOfBattle_CoinCase(u8 taskId) { ConvertIntToDecimalStringN(gStringVar1, GetCoins(), STR_CONV_MODE_LEFT_ALIGN, 4); @@ -797,6 +810,12 @@ void ItemUseOutOfBattle_AbilityPatch(u8 taskId) SetUpItemUseCallback(taskId); } +void ItemUseOutOfBattle_Mint(u8 taskId) +{ + gItemUseCB = ItemUseCB_Mint; + SetUpItemUseCallback(taskId); +} + void ItemUseOutOfBattle_ResetEVs(u8 taskId) { gItemUseCB = ItemUseCB_ResetEVs; @@ -833,6 +852,12 @@ void ItemUseOutOfBattle_RareCandy(u8 taskId) SetUpItemUseCallback(taskId); } +void ItemUseOutOfBattle_DynamaxCandy(u8 taskId) +{ + gItemUseCB = ItemUseCB_DynamaxCandy; + SetUpItemUseCallback(taskId); +} + void ItemUseOutOfBattle_TMHM(u8 taskId) { if (gSpecialVar_ItemId >= ITEM_HM01) diff --git a/src/load_save.c b/src/load_save.c index d42b71a4a990..667f9e1c3cc9 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -175,7 +175,17 @@ void LoadPlayerParty(void) gPlayerPartyCount = gSaveBlock1Ptr->playerPartyCount; for (i = 0; i < PARTY_SIZE; i++) + { + u32 data; gPlayerParty[i] = gSaveBlock1Ptr->playerParty[i]; + + // TODO: Turn this into a save migration once those are available. + // At which point we can remove hp and status from Pokemon entirely. + data = gPlayerParty[i].maxHP - gPlayerParty[i].hp; + SetBoxMonData(&gPlayerParty[i].box, MON_DATA_HP_LOST, &data); + data = gPlayerParty[i].status; + SetBoxMonData(&gPlayerParty[i].box, MON_DATA_STATUS, &data); + } } void SaveObjectEvents(void) 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..54d25c1c10c9 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); @@ -372,7 +373,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/main_menu.c b/src/main_menu.c index c7295bd8637c..c1f092b2ca76 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -1876,7 +1876,7 @@ static void SpriteCB_MovePlayerDownWhileShrinking(struct Sprite *sprite) static u8 NewGameBirchSpeech_CreateLotadSprite(u8 x, u8 y) { - return CreateMonPicSprite_Affine(SPECIES_LOTAD, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE); + return CreateMonPicSprite_Affine(SPECIES_LOTAD, FALSE, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE); } static void AddBirchSpeechObjects(u8 taskId) diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c index 0b4a950ad5f0..0c0714354a4f 100644 --- a/src/mauville_old_man.c +++ b/src/mauville_old_man.c @@ -320,11 +320,7 @@ static void InitGiddyTaleList(void) // Shuffle question list for (i = 0; i < GIDDY_MAX_QUESTIONS; i++) giddy->questionList[i] = i; - for (i = 0; i < GIDDY_MAX_QUESTIONS; i++) - { - var = Random() % (i + 1); - SWAP(giddy->questionList[i], giddy->questionList[var], temp); - } + Shuffle(giddy->questionList, GIDDY_MAX_QUESTIONS, sizeof(giddy->questionList[0])); // Count total number of words in above word groups totalWords = 0; @@ -1265,27 +1261,12 @@ static void StorytellerRecordNewStat(u32 player, u32 stat) sStorytellerPtr->language[player] = gGameLanguage; } -static void ScrambleStatList(u8 *arr, s32 count) -{ - s32 i; - - for (i = 0; i < count; i++) - arr[i] = i; - for (i = 0; i < count; i++) - { - u32 a = Random() % count; - u32 b = Random() % count; - u8 temp; - SWAP(arr[a], arr[b], temp); - } -} - static bool8 StorytellerInitializeRandomStat(void) { u8 storyIds[sNumStories]; s32 i, j; - ScrambleStatList(storyIds, sNumStories); + Shuffle(storyIds, sNumStories, sizeof(storyIds[0])); for (i = 0; i < sNumStories; i++) { u8 stat = sStorytellerStories[storyIds[i]].stat; @@ -1427,4 +1408,3 @@ bool8 Script_StorytellerInitializeRandomStat(void) sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller; return StorytellerInitializeRandomStat(); } - diff --git a/src/menu_specialized.c b/src/menu_specialized.c index c99c71e4b530..125a9356665b 100644 --- a/src/menu_specialized.c +++ b/src/menu_specialized.c @@ -1075,11 +1075,11 @@ void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId, if (partyId != numMons) { u16 species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL); - u32 trainerId = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL); + bool8 isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL); u32 personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL); LoadSpecialPokePic(tilesDst, species, personality, TRUE); - LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), palDst); + LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), palDst); } } diff --git a/src/mirage_tower.c b/src/mirage_tower.c index b1e2e5003b0f..78dec7a15b75 100644 --- a/src/mirage_tower.c +++ b/src/mirage_tower.c @@ -598,13 +598,9 @@ static void DoMirageTowerDisintegration(u8 taskId) sFallingTower[index].disintegrateRand[i] = i; // Randomize disintegration pattern - for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++) - { - u16 rand1, rand2, temp; - rand1 = Random() % INNER_BUFFER_LENGTH; - rand2 = Random() % INNER_BUFFER_LENGTH; - SWAP(sFallingTower[index].disintegrateRand[rand2], sFallingTower[index].disintegrateRand[rand1], temp); - } + Shuffle(sFallingTower[index].disintegrateRand, INNER_BUFFER_LENGTH, + sizeof(sFallingTower[index].disintegrateRand[0])); + if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1)) gTasks[taskId].data[3]++; gTasks[taskId].data[1] = 0; @@ -702,13 +698,8 @@ static void Task_FossilFallAndSink(u8 taskId) break; case 6: // Randomize disintegration pattern - for (i = 0; i < FOSSIL_DISINTEGRATE_LENGTH * sizeof(u16); i++) - { - u16 rand1, rand2, temp; - rand1 = Random() % FOSSIL_DISINTEGRATE_LENGTH; - rand2 = Random() % FOSSIL_DISINTEGRATE_LENGTH; - SWAP(sFallingFossil->disintegrateRand[rand2], sFallingFossil->disintegrateRand[rand1], temp); - } + Shuffle(sFallingFossil->disintegrateRand, FOSSIL_DISINTEGRATE_LENGTH, + sizeof(sFallingFossil->disintegrateRand[0])); gSprites[sFallingFossil->spriteId].callback = SpriteCB_FallingFossil; break; case 7: 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 e97310058652..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, }; @@ -4691,7 +4691,7 @@ void Task_AbilityCapsule(u8 taskId) } gPartyMenuUseExitCallback = TRUE; GetMonNickname(&gPlayerParty[tMonId], gStringVar1); - StringCopy(gStringVar2, gAbilityNames[GetAbilityBySpecies(tSpecies, tAbilityNum)]); + StringCopy(gStringVar2, gAbilities[GetAbilityBySpecies(tSpecies, tAbilityNum)].name); StringExpandPlaceholders(gStringVar4, askText); PlaySE(SE_SELECT); DisplayPartyMenuMessage(gStringVar4, 1); @@ -4778,7 +4778,7 @@ void Task_AbilityPatch(u8 taskId) } gPartyMenuUseExitCallback = TRUE; GetMonNickname(&gPlayerParty[tMonId], gStringVar1); - StringCopy(gStringVar2, gAbilityNames[GetAbilityBySpecies(tSpecies, tAbilityNum)]); + StringCopy(gStringVar2, gAbilities[GetAbilityBySpecies(tSpecies, tAbilityNum)].name); StringExpandPlaceholders(gStringVar4, askText); PlaySE(SE_SELECT); DisplayPartyMenuMessage(gStringVar4, 1); @@ -4851,6 +4851,104 @@ void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task) #undef tMonId #undef tOldFunc +#define tState data[0] +#define tMonId data[1] +#define tOldNature data[2] +#define tNewNature data[3] +#define tOldFunc 4 + +void Task_Mint(u8 taskId) +{ + static const u8 askText[] = _("It might affect {STR_VAR_1}'s stats.\nAre you sure you want to use it?"); + static const u8 doneText[] = _("{STR_VAR_1}'s stats may have changed due\nto the effects of the {STR_VAR_2}!{PAUSE_UNTIL_PRESS}"); + s16 *data = gTasks[taskId].data; + + switch (tState) + { + case 0: + // Can't use. + if (tOldNature == tNewNature) + { + gPartyMenuUseExitCallback = FALSE; + PlaySE(SE_SELECT); + DisplayPartyMenuMessage(gText_WontHaveEffect, 1); + ScheduleBgCopyTilemapToVram(2); + gTasks[taskId].func = Task_ClosePartyMenuAfterText; + return; + } + gPartyMenuUseExitCallback = TRUE; + GetMonNickname(&gPlayerParty[tMonId], gStringVar1); + CopyItemName(gSpecialVar_ItemId, gStringVar2); + StringExpandPlaceholders(gStringVar4, askText); + PlaySE(SE_SELECT); + DisplayPartyMenuMessage(gStringVar4, 1); + ScheduleBgCopyTilemapToVram(2); + tState++; + break; + case 1: + if (!IsPartyMenuTextPrinterActive()) + { + PartyMenuDisplayYesNoMenu(); + tState++; + } + break; + case 2: + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case 0: + tState++; + break; + case 1: + case MENU_B_PRESSED: + gPartyMenuUseExitCallback = FALSE; + PlaySE(SE_SELECT); + ScheduleBgCopyTilemapToVram(2); + // Don't exit party selections screen, return to choosing a mon. + ClearStdWindowAndFrameToTransparent(6, 0); + ClearWindowTilemap(6); + DisplayPartyMenuStdMessage(5); + gTasks[taskId].func = (void *)GetWordTaskArg(taskId, tOldFunc); + return; + } + break; + case 3: + PlaySE(SE_USE_ITEM); + StringExpandPlaceholders(gStringVar4, doneText); + DisplayPartyMenuMessage(gStringVar4, 1); + ScheduleBgCopyTilemapToVram(2); + tState++; + break; + case 4: + if (!IsPartyMenuTextPrinterActive()) + tState++; + break; + case 5: + SetMonData(&gPlayerParty[tMonId], MON_DATA_HIDDEN_NATURE, &tNewNature); + CalculateMonStats(&gPlayerParty[tMonId]); + RemoveBagItem(gSpecialVar_ItemId, 1); + gTasks[taskId].func = Task_ClosePartyMenu; + break; + } +} + +void ItemUseCB_Mint(u8 taskId, TaskFunc task) +{ + s16 *data = gTasks[taskId].data; + + tState = 0; + tMonId = gPartyMenu.slotId; + tOldNature = GetMonData(&gPlayerParty[tMonId], MON_DATA_HIDDEN_NATURE); + tNewNature = ItemId_GetSecondaryId(gSpecialVar_ItemId); + SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func)); + gTasks[taskId].func = Task_Mint; +} + +#undef tState +#undef tMonId +#undef tOldNature +#undef tNewNature +#undef tOldFunc + static void Task_DisplayHPRestoredMessage(u8 taskId) { GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1); @@ -5672,6 +5770,70 @@ static void BufferMonStatsToTaskData(struct Pokemon *mon, s16 *data) data[3] = GetMonData(mon, MON_DATA_SPEED); } +#define tState data[0] +#define tMonId data[1] +#define tDynamaxLevel data[2] +#define tOldFunc 4 + +void Task_DynamaxCandy(u8 taskId) +{ + static const u8 doneText[] = _("{STR_VAR_1}'s Dynamax Level\nincreased by 1!{PAUSE_UNTIL_PRESS}"); + s16 *data = gTasks[taskId].data; + + switch (tState) + { + case 0: + // Can't use. + if (tDynamaxLevel == MAX_DYNAMAX_LEVEL) + { + gPartyMenuUseExitCallback = FALSE; + PlaySE(SE_SELECT); + DisplayPartyMenuMessage(gText_WontHaveEffect, 1); + ScheduleBgCopyTilemapToVram(2); + gTasks[taskId].func = Task_ClosePartyMenuAfterText; + return; + } + gPartyMenuUseExitCallback = TRUE; + GetMonNickname(&gPlayerParty[tMonId], gStringVar1); + CopyItemName(gSpecialVar_ItemId, gStringVar2); + tState++; + break; + case 1: + PlaySE(SE_USE_ITEM); + StringExpandPlaceholders(gStringVar4, doneText); + DisplayPartyMenuMessage(gStringVar4, 1); + ScheduleBgCopyTilemapToVram(2); + tState++; + break; + case 2: + if (!IsPartyMenuTextPrinterActive()) + tState++; + break; + case 3: + tDynamaxLevel++; + SetMonData(&gPlayerParty[tMonId], MON_DATA_DYNAMAX_LEVEL, &tDynamaxLevel); + RemoveBagItem(gSpecialVar_ItemId, 1); + gTasks[taskId].func = Task_ClosePartyMenu; + break; + } +} + +void ItemUseCB_DynamaxCandy(u8 taskId, TaskFunc task) +{ + s16 *data = gTasks[taskId].data; + + tState = 0; + tMonId = gPartyMenu.slotId; + tDynamaxLevel = GetMonData(&gPlayerParty[tMonId], MON_DATA_DYNAMAX_LEVEL); + SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func)); + gTasks[taskId].func = Task_DynamaxCandy; +} + +#undef tState +#undef tMonId +#undef tDynamaxLevel +#undef tOldFunc + #define tUsedOnSlot data[0] #define tHadEffect data[1] #define tLastSlotUsed data[2] @@ -6946,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/pokeblock_feed.c b/src/pokeblock_feed.c index c7ef8c9e9049..61e1b7a6b366 100644 --- a/src/pokeblock_feed.c +++ b/src/pokeblock_feed.c @@ -718,7 +718,8 @@ static void HandleInitBackgrounds(void) static bool8 LoadMonAndSceneGfx(struct Pokemon *mon) { u16 species; - u32 personality, trainerId; + u32 personality; + bool32 isShiny; switch (sPokeblockFeed->loadGfxState) { @@ -733,8 +734,8 @@ static bool8 LoadMonAndSceneGfx(struct Pokemon *mon) // Load mon palette species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG); personality = GetMonData(mon, MON_DATA_PERSONALITY); - trainerId = GetMonData(mon, MON_DATA_OT_ID); - LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, trainerId, personality), species); + isShiny = GetMonData(mon, MON_DATA_IS_SHINY); + LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species); SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT); sPokeblockFeed->loadGfxState++; break; diff --git a/src/pokedex.c b/src/pokedex.c index 33b7dd02ddf1..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) @@ -3971,12 +3971,11 @@ static void HighlightSubmenuScreenSelectBarItem(u8 a, u16 b) #define tSpecies data[1] #define tPalTimer data[2] #define tMonSpriteId data[3] -#define tOtIdLo data[12] -#define tOtIdHi data[13] +#define tIsShiny data[13] #define tPersonalityLo data[14] #define tPersonalityHi data[15] -u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality) +u8 DisplayCaughtMonDexPage(u16 species, bool32 isShiny, u32 personality) { u8 taskId = 0; if (POKEDEX_PLUS_HGSS) @@ -3986,8 +3985,7 @@ u8 DisplayCaughtMonDexPage(u16 species, u32 otId, u32 personality) gTasks[taskId].tState = 0; gTasks[taskId].tSpecies = species; - gTasks[taskId].tOtIdLo = otId; - gTasks[taskId].tOtIdHi = otId >> 16; + gTasks[taskId].tIsShiny = isShiny; gTasks[taskId].tPersonalityLo = personality; gTasks[taskId].tPersonalityHi = personality >> 16; return taskId; @@ -4039,7 +4037,7 @@ static void Task_DisplayCaughtMonDexPage(u8 taskId) gTasks[taskId].tState++; break; case 4: - spriteId = CreateMonPicSprite(NationalPokedexNumToSpecies(dexNum), 0, ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo, TRUE, MON_PAGE_X, MON_PAGE_Y, 0, TAG_NONE); + spriteId = CreateMonPicSprite(NationalPokedexNumToSpecies(dexNum), FALSE, ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo, TRUE, MON_PAGE_X, MON_PAGE_Y, 0, TAG_NONE); gSprites[spriteId].oam.priority = 0; BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK); SetVBlankCallback(gPokedexVBlankCB); @@ -4089,7 +4087,7 @@ static void Task_ExitCaughtMonPage(u8 taskId) { if (!gPaletteFade.active) { - u32 otId; + bool32 isShiny; u32 personality; u8 paletteNum; const u32 *lzPaletteData; @@ -4104,10 +4102,10 @@ static void Task_ExitCaughtMonPage(u8 taskId) if (buffer) Free(buffer); - otId = ((u16)gTasks[taskId].tOtIdHi << 16) | (u16)gTasks[taskId].tOtIdLo; + isShiny = (bool8)gTasks[taskId].tIsShiny; personality = ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo; paletteNum = gSprites[gTasks[taskId].tMonSpriteId].oam.paletteNum; - lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(gTasks[taskId].tSpecies, otId, personality); + lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(gTasks[taskId].tSpecies, isShiny, personality); LoadCompressedPalette(lzPaletteData, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); DestroyTask(taskId); } @@ -4654,7 +4652,7 @@ static u32 GetPokedexMonPersonality(u16 species) u16 CreateMonSpriteFromNationalDexNumber(u16 nationalNum, s16 x, s16 y, u16 paletteSlot) { nationalNum = NationalPokedexNumToSpecies(nationalNum); - return CreateMonPicSprite(nationalNum, SHINY_ODDS, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE); + return CreateMonPicSprite(nationalNum, FALSE, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE); } static u16 GetPokemonScaleFromNationalDexNumber(u16 nationalNum) diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c index 27fac583ae27..6526af075d13 100644 --- a/src/pokedex_plus_hgss.c +++ b/src/pokedex_plus_hgss.c @@ -4738,7 +4738,7 @@ static u32 GetPokedexMonPersonality(u16 species) static u16 CreateMonSpriteFromNationalDexNumberHGSS(u16 nationalNum, s16 x, s16 y, u16 paletteSlot) { nationalNum = NationalPokedexNumToSpeciesHGSS(nationalNum); - return CreateMonPicSprite(nationalNum, SHINY_ODDS, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE); + return CreateMonPicSprite(nationalNum, FALSE, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, TAG_NONE); } static u16 GetPokemonScaleFromNationalDexNumber(u16 nationalNum) @@ -6043,21 +6043,21 @@ static void PrintStatsScreen_Abilities(u8 taskId) if (gTasks[taskId].data[5] == 0) { ability0 = sPokedexView->sPokemonStats.ability0; - PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[ability0], abilities_x, abilities_y); - PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[ability0], abilities_x, abilities_y + 14); + PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[ability0].name, abilities_x, abilities_y); + PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[ability0].description, abilities_x, abilities_y + 14); ability1 = sPokedexView->sPokemonStats.ability1; if (ability1 != ABILITY_NONE && ability1 != ability0) { - PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[ability1], abilities_x, abilities_y + 30); - PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[ability1], abilities_x, abilities_y + 44); + PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[ability1].name, abilities_x, abilities_y + 30); + PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[ability1].description, abilities_x, abilities_y + 44); } } else //Hidden abilities { abilityHidden = sPokedexView->sPokemonStats.abilityHidden; - PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilityNames[abilityHidden], abilities_x, abilities_y); - PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilityDescriptionPointers[abilityHidden], abilities_x, abilities_y + 14); + PrintStatsScreenTextSmallWhite(WIN_STATS_ABILITIES, gAbilities[abilityHidden].name, abilities_x, abilities_y); + PrintStatsScreenTextSmall(WIN_STATS_ABILITIES, gAbilities[abilityHidden].description, abilities_x, abilities_y + 14); } } diff --git a/src/pokemon.c b/src/pokemon.c index f89a37c61ea6..a2e357f13416 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -87,6 +87,7 @@ EWRAM_DATA static struct MonSpritesGfxManager *sMonSpritesGfxManagers[MON_SPR_GF EWRAM_DATA static u8 sTriedEvolving = 0; #include "data/battle_moves.h" +#include "data/abilities.h" // Used in an unreferenced function in RS. // Unreferenced here and in FRLG. @@ -673,6 +674,63 @@ static const struct SpriteTemplate sSpriteTemplate_64x64 = .callback = SpriteCallbackDummy, }; +// NOTE: Reordering this array will break compatibility with existing +// saves. +static const u32 sCompressedStatuses[] = +{ + STATUS1_NONE, + STATUS1_SLEEP_TURN(1), + STATUS1_SLEEP_TURN(2), + STATUS1_SLEEP_TURN(3), + STATUS1_SLEEP_TURN(4), + STATUS1_SLEEP_TURN(5), + STATUS1_POISON, + STATUS1_BURN, + STATUS1_FREEZE, + STATUS1_PARALYSIS, + STATUS1_TOXIC_POISON, + STATUS1_FROSTBITE, +}; + +// Attempt to detect situations where the BoxPokemon struct is unable to +// contain all the values. +// TODO: Is it possible to compute: +// - The maximum experience. +// - The maximum PP. +// - The maximum HP. +// - The maximum form countdown. +STATIC_ASSERT(NUM_SPECIES < (1 << 11), PokemonSubstruct0_species_TooSmall); +STATIC_ASSERT(NUMBER_OF_MON_TYPES + 1 <= (1 << 5), PokemonSubstruct0_teraType_TooSmall); +STATIC_ASSERT(ITEMS_COUNT < (1 << 10), PokemonSubstruct0_heldItem_TooSmall); +STATIC_ASSERT(MAX_LEVEL <= 100, PokemonSubstruct0_experience_PotentiallTooSmall); // Maximum of ~2 million exp. +STATIC_ASSERT(LAST_BALL < (1 << 6), PokemonSubstruct0_pokeball_TooSmall); +STATIC_ASSERT(MOVES_COUNT_ALL < (1 << 11), PokemonSubstruct1_moves_TooSmall); +STATIC_ASSERT(ARRAY_COUNT(sCompressedStatuses) <= (1 << 4), PokemonSubstruct3_compressedStatus_TooSmall); +STATIC_ASSERT(MAX_LEVEL < (1 << 7), PokemonSubstruct3_metLevel_TooSmall); +STATIC_ASSERT(NUM_VERSIONS < (1 << 4), PokemonSubstruct3_metGame_TooSmall); +STATIC_ASSERT(MAX_DYNAMAX_LEVEL < (1 << 4), PokemonSubstruct3_dynamaxLevel_TooSmall); +STATIC_ASSERT(MAX_PER_STAT_IVS < (1 << 5), PokemonSubstruct3_ivs_TooSmall); +STATIC_ASSERT(NUM_NATURES <= (1 << 5), BoxPokemon_hiddenNatureModifier_TooSmall); + +static u32 CompressStatus(u32 status) +{ + s32 i; + for (i = 0; i < ARRAY_COUNT(sCompressedStatuses); i++) + { + if (sCompressedStatuses[i] == status) + return i; + } + return 0; // STATUS1_NONE +} + +static u32 UncompressStatus(u32 compressedStatus) +{ + if (compressedStatus < ARRAY_COUNT(sCompressedStatuses)) + return sCompressedStatuses[compressedStatus]; + else + return STATUS1_NONE; +} + void ZeroBoxMonData(struct BoxPokemon *boxMon) { u8 *raw = (u8 *)boxMon; @@ -733,6 +791,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 i; u8 availableIVs[NUM_STATS]; u8 selectedIvs[LEGENDARY_PERFECT_IV_COUNT]; + bool32 isShiny; ZeroBoxMonData(boxMon); @@ -744,17 +803,13 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, // Determine original trainer ID if (otIdType == OT_ID_RANDOM_NO_SHINY) { - u32 shinyValue; - do - { - // Choose random OT IDs until one that results in a non-shiny Pokémon - value = Random32(); - shinyValue = GET_SHINY_VALUE(value, personality); - } while (shinyValue < SHINY_ODDS); + value = Random32(); + isShiny = FALSE; } else if (otIdType == OT_ID_PRESET) { value = fixedOtId; + isShiny = GET_SHINY_VALUE(value, personality) < SHINY_ODDS; } else // Player is the OT { @@ -763,26 +818,15 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24); -#if P_FLAG_FORCE_NO_SHINY != 0 - if (FlagGet(P_FLAG_FORCE_NO_SHINY)) + if (P_FLAG_FORCE_NO_SHINY != 0 && FlagGet(P_FLAG_FORCE_NO_SHINY)) { - while (GET_SHINY_VALUE(value, personality) < SHINY_ODDS) - personality = Random32(); + isShiny = FALSE; } -#endif -#if P_FLAG_FORCE_SHINY != 0 - #if P_FLAG_FORCE_NO_SHINY != 0 - else - #endif - if (FlagGet(P_FLAG_FORCE_SHINY)) + else if (P_FLAG_FORCE_SHINY != 0 && FlagGet(P_FLAG_FORCE_SHINY)) { - while (GET_SHINY_VALUE(value, personality) >= SHINY_ODDS) - personality = Random32(); + isShiny = TRUE; } -#endif -#if P_FLAG_FORCE_SHINY != 0 || P_FLAG_FORCE_NO_SHINY != 0 else -#endif { u32 totalRerolls = 0; if (CheckBagHasItem(ITEM_SHINY_CHARM, 1)) @@ -795,6 +839,8 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, personality = Random32(); totalRerolls--; } + + isShiny = GET_SHINY_VALUE(value, personality) < SHINY_ODDS; } } @@ -804,6 +850,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, checksum = CalculateBoxMonChecksum(boxMon); SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum); EncryptBoxMon(boxMon); + SetBoxMonData(boxMon, MON_DATA_IS_SHINY, &isShiny); StringCopy(speciesName, GetSpeciesName(species)); SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName); SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage); @@ -1382,7 +1429,6 @@ static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon) { \ u8 baseStat = gSpeciesInfo[species].base; \ s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \ - u8 nature = GetNature(mon); \ n = ModifyStatByNature(nature, n, statIndex); \ if (B_FRIENDSHIP_BOOST == TRUE) \ n = n + ((n * 10 * friendship) / (MAX_FRIENDSHIP * 100));\ @@ -1393,23 +1439,25 @@ void CalculateMonStats(struct Pokemon *mon) { s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL); s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL); - s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL); + s32 hpIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_HP) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_HP_IV, NULL); s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL); - s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL); + s32 attackIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_ATK) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_ATK_IV, NULL); s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL); - s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL); + s32 defenseIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_DEF) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_DEF_IV, NULL); s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL); - s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL); + s32 speedIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPEED) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPEED_IV, NULL); s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL); - s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL); + s32 spAttackIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPATK) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPATK_IV, NULL); s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL); - s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL); + s32 spDefenseIV = GetMonData(mon, MON_DATA_HYPER_TRAINED_SPDEF) ? MAX_PER_STAT_IVS : GetMonData(mon, MON_DATA_SPDEF_IV, NULL); s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL); u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); u8 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); s32 level = GetLevelFromMonExp(mon); s32 newMaxHP; + u8 nature = GetMonData(mon, MON_DATA_HIDDEN_NATURE, NULL); + SetMonData(mon, MON_DATA_LEVEL, &level); if (species == SPECIES_SHEDINJA) @@ -1465,12 +1513,15 @@ void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest) { u32 value = 0; dest->box = *src; - SetMonData(dest, MON_DATA_STATUS, &value); - SetMonData(dest, MON_DATA_HP, &value); - SetMonData(dest, MON_DATA_MAX_HP, &value); + dest->status = GetBoxMonData(&dest->box, MON_DATA_STATUS, NULL); + dest->hp = 0; + dest->maxHP = 0; value = MAIL_NONE; SetMonData(dest, MON_DATA_MAIL, &value); + value = GetBoxMonData(&dest->box, MON_DATA_HP_LOST); CalculateMonStats(dest); + value = GetMonData(dest, MON_DATA_MAX_HP) - value; + SetMonData(dest, MON_DATA_HP, &value); } u8 GetLevelFromMonExp(struct Pokemon *mon) @@ -2044,6 +2095,76 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) switch (field) { + case MON_DATA_NICKNAME: + { + if (boxMon->isBadEgg) + { + for (retVal = 0; + retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; + data[retVal] = gText_BadEgg[retVal], retVal++) {} + + data[retVal] = EOS; + } + else if (boxMon->isEgg) + { + StringCopy(data, gText_EggNickname); + retVal = StringLength(data); + } + else if (boxMon->language == LANGUAGE_JAPANESE) + { + data[0] = EXT_CTRL_CODE_BEGIN; + data[1] = EXT_CTRL_CODE_JPN; + + for (retVal = 2, i = 0; + i < 5 && boxMon->nickname[i] != EOS; + data[retVal] = boxMon->nickname[i], retVal++, i++) {} + + data[retVal++] = EXT_CTRL_CODE_BEGIN; + data[retVal++] = EXT_CTRL_CODE_ENG; + data[retVal] = EOS; + } + else + { + retVal = 0; + while (retVal < min(sizeof(boxMon->nickname), POKEMON_NAME_LENGTH)) + { + data[retVal] = boxMon->nickname[retVal]; + retVal++; + } + + // Vanilla Pokémon have 0s in nickname11 and nickname12 + // so if both are 0 we assume that this is a vanilla + // Pokémon and replace them with EOS. This means that + // two CHAR_SPACE at the end of a nickname are trimmed. + if (POKEMON_NAME_LENGTH >= 12) + { + if (substruct0->nickname11 == 0 && substruct0->nickname12 == 0) + { + data[retVal++] = EOS; + data[retVal++] = EOS; + } + else + { + data[retVal++] = substruct0->nickname11; + data[retVal++] = substruct0->nickname12; + } + } + else if (POKEMON_NAME_LENGTH >= 11) + { + if (substruct0->nickname11 == 0) + { + data[retVal++] = EOS; + } + else + { + data[retVal++] = substruct0->nickname11; + } + } + + data[retVal] = EOS; + } + break; + } case MON_DATA_SPECIES: retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species; break; @@ -2060,16 +2181,28 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) retVal = substruct0->friendship; break; case MON_DATA_MOVE1: + retVal = substruct1->move1; + break; case MON_DATA_MOVE2: + retVal = substruct1->move2; + break; case MON_DATA_MOVE3: + retVal = substruct1->move3; + break; case MON_DATA_MOVE4: - retVal = substruct1->moves[field - MON_DATA_MOVE1]; + retVal = substruct1->move4; break; case MON_DATA_PP1: + retVal = substruct1->pp1; + break; case MON_DATA_PP2: + retVal = substruct1->pp2; + break; case MON_DATA_PP3: + retVal = substruct1->pp3; + break; case MON_DATA_PP4: - retVal = substruct1->pp[field - MON_DATA_PP1]; + retVal = substruct1->pp4; break; case MON_DATA_HP_EV: retVal = substruct2->hpEV; @@ -2200,9 +2333,6 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_WORLD_RIBBON: retVal = substruct3->worldRibbon; break; - case MON_DATA_UNUSED_RIBBONS: - retVal = substruct3->unusedRibbons; - break; case MON_DATA_MODERN_FATEFUL_ENCOUNTER: retVal = substruct3->modernFatefulEncounter; break; @@ -2228,10 +2358,10 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) while (moves[i] != MOVES_COUNT) { u16 move = moves[i]; - if (substruct1->moves[0] == move - || substruct1->moves[1] == move - || substruct1->moves[2] == move - || substruct1->moves[3] == move) + if (substruct1->move1 == move + || substruct1->move2 == move + || substruct1->move3 == move + || substruct1->move4 == move) retVal |= gBitTable[i]; i++; } @@ -2283,6 +2413,46 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) | (substruct3->worldRibbon << 26); } break; + case MON_DATA_HYPER_TRAINED_HP: + retVal = substruct1->hyperTrainedHP; + break; + case MON_DATA_HYPER_TRAINED_ATK: + retVal = substruct1->hyperTrainedAttack; + break; + case MON_DATA_HYPER_TRAINED_DEF: + retVal = substruct1->hyperTrainedDefense; + break; + case MON_DATA_HYPER_TRAINED_SPEED: + retVal = substruct1->hyperTrainedSpeed; + break; + case MON_DATA_HYPER_TRAINED_SPATK: + retVal = substruct1->hyperTrainedSpAttack; + break; + case MON_DATA_HYPER_TRAINED_SPDEF: + retVal = substruct1->hyperTrainedSpDefense; + break; + case MON_DATA_IS_SHADOW: + retVal = substruct3->isShadow; + break; + case MON_DATA_DYNAMAX_LEVEL: + retVal = substruct3->dynamaxLevel; + break; + case MON_DATA_GIGANTAMAX_FACTOR: + retVal = substruct3->gigantamaxFactor; + break; + case MON_DATA_TERA_TYPE: + { + if (substruct0->teraType == 0) + { + const u8 *types = gSpeciesInfo[substruct0->species].types; + retVal = (boxMon->personality & 0x1) == 0 ? types[0] : types[1]; + } + else + { + retVal = substruct0->teraType - 1; + } + break; + } default: break; } @@ -2291,50 +2461,18 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) { switch (field) { + case MON_DATA_STATUS: + retVal = UncompressStatus(boxMon->compressedStatus); + break; + case MON_DATA_HP_LOST: + retVal = boxMon->hpLost; + break; case MON_DATA_PERSONALITY: retVal = boxMon->personality; break; case MON_DATA_OT_ID: retVal = boxMon->otId; break; - case MON_DATA_NICKNAME: - { - if (boxMon->isBadEgg) - { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; - data[retVal] = gText_BadEgg[retVal], retVal++) {} - - data[retVal] = EOS; - } - else if (boxMon->isEgg) - { - StringCopy(data, gText_EggNickname); - retVal = StringLength(data); - } - else if (boxMon->language == LANGUAGE_JAPANESE) - { - data[0] = EXT_CTRL_CODE_BEGIN; - data[1] = EXT_CTRL_CODE_JPN; - - for (retVal = 2, i = 0; - i < 5 && boxMon->nickname[i] != EOS; - data[retVal] = boxMon->nickname[i], retVal++, i++) {} - - data[retVal++] = EXT_CTRL_CODE_BEGIN; - data[retVal++] = EXT_CTRL_CODE_ENG; - data[retVal] = EOS; - } - else - { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH; - data[retVal] = boxMon->nickname[retVal], retVal++){} - - data[retVal] = EOS; - } - break; - } case MON_DATA_LANGUAGE: retVal = boxMon->language; break; @@ -2366,9 +2504,18 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) case MON_DATA_CHECKSUM: retVal = boxMon->checksum; break; - case MON_DATA_ENCRYPT_SEPARATOR: - retVal = boxMon->unknown; + case MON_DATA_IS_SHINY: + { + u32 shinyValue = GET_SHINY_VALUE(boxMon->otId, boxMon->personality); + retVal = (shinyValue < SHINY_ODDS) ^ boxMon->shinyModifier; + break; + } + case MON_DATA_HIDDEN_NATURE: + { + u32 nature = GetNatureFromPersonality(boxMon->personality); + retVal = nature ^ boxMon->hiddenNatureModifier; break; + } default: break; } @@ -2397,13 +2544,27 @@ void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg) { case MON_DATA_STATUS: SET32(mon->status); + SetBoxMonData(&mon->box, MON_DATA_STATUS, dataArg); break; case MON_DATA_LEVEL: SET8(mon->level); break; case MON_DATA_HP: + { + u32 hpLost; SET16(mon->hp); + hpLost = mon->maxHP - mon->hp; + SetBoxMonData(&mon->box, MON_DATA_HP_LOST, &hpLost); + break; + } + case MON_DATA_HP_LOST: + { + u32 hpLost; + SET16(hpLost); + mon->hp = mon->maxHP - hpLost; + SetBoxMonData(&mon->box, MON_DATA_HP_LOST, &hpLost); break; + } case MON_DATA_MAX_HP: SET16(mon->maxHP); break; @@ -2462,6 +2623,17 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) switch (field) { + case MON_DATA_NICKNAME: + { + s32 i; + for (i = 0; i < min(sizeof(boxMon->nickname), POKEMON_NAME_LENGTH); i++) + boxMon->nickname[i] = data[i]; + if (POKEMON_NAME_LENGTH >= 11) + substruct0->nickname11 = data[10]; + if (POKEMON_NAME_LENGTH >= 12) + substruct0->nickname12 = data[11]; + break; + } case MON_DATA_SPECIES: { SET16(substruct0->species); @@ -2484,16 +2656,28 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) SET8(substruct0->friendship); break; case MON_DATA_MOVE1: + SET16(substruct1->move1); + break; case MON_DATA_MOVE2: + SET16(substruct1->move2); + break; case MON_DATA_MOVE3: + SET16(substruct1->move3); + break; case MON_DATA_MOVE4: - SET16(substruct1->moves[field - MON_DATA_MOVE1]); + SET16(substruct1->move4); break; case MON_DATA_PP1: + SET8(substruct1->pp1); + break; case MON_DATA_PP2: + SET8(substruct1->pp2); + break; case MON_DATA_PP3: + SET8(substruct1->pp3); + break; case MON_DATA_PP4: - SET8(substruct1->pp[field - MON_DATA_PP1]); + SET8(substruct1->pp4); break; case MON_DATA_HP_EV: SET8(substruct2->hpEV); @@ -2634,9 +2818,6 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_WORLD_RIBBON: SET8(substruct3->worldRibbon); break; - case MON_DATA_UNUSED_RIBBONS: - SET8(substruct3->unusedRibbons); - break; case MON_DATA_MODERN_FATEFUL_ENCOUNTER: SET8(substruct3->modernFatefulEncounter); break; @@ -2651,6 +2832,40 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) substruct3->spDefenseIV = (ivs >> 25) & MAX_IV_MASK; break; } + case MON_DATA_HYPER_TRAINED_HP: + SET8(substruct1->hyperTrainedHP); + break; + case MON_DATA_HYPER_TRAINED_ATK: + SET8(substruct1->hyperTrainedAttack); + break; + case MON_DATA_HYPER_TRAINED_DEF: + SET8(substruct1->hyperTrainedDefense); + break; + case MON_DATA_HYPER_TRAINED_SPEED: + SET8(substruct1->hyperTrainedSpeed); + break; + case MON_DATA_HYPER_TRAINED_SPATK: + SET8(substruct1->hyperTrainedSpAttack); + break; + case MON_DATA_HYPER_TRAINED_SPDEF: + SET8(substruct1->hyperTrainedSpDefense); + break; + case MON_DATA_IS_SHADOW: + SET8(substruct3->isShadow); + break; + case MON_DATA_DYNAMAX_LEVEL: + SET8(substruct3->dynamaxLevel); + break; + case MON_DATA_GIGANTAMAX_FACTOR: + SET8(substruct3->gigantamaxFactor); + break; + case MON_DATA_TERA_TYPE: + { + u32 teraType; + SET8(teraType); + substruct0->teraType = 1 + teraType; + break; + } default: break; } @@ -2659,19 +2874,22 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) { switch (field) { + case MON_DATA_STATUS: + { + u32 status; + SET32(status); + boxMon->compressedStatus = CompressStatus(status); + break; + } + case MON_DATA_HP_LOST: + SET16(boxMon->hpLost); + break; case MON_DATA_PERSONALITY: SET32(boxMon->personality); break; case MON_DATA_OT_ID: SET32(boxMon->otId); break; - case MON_DATA_NICKNAME: - { - s32 i; - for (i = 0; i < POKEMON_NAME_LENGTH; i++) - boxMon->nickname[i] = data[i]; - break; - } case MON_DATA_LANGUAGE: SET8(boxMon->language); break; @@ -2697,10 +2915,23 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) case MON_DATA_CHECKSUM: SET16(boxMon->checksum); break; - case MON_DATA_ENCRYPT_SEPARATOR: - SET16(boxMon->unknown); + case MON_DATA_IS_SHINY: + { + u32 shinyValue = GET_SHINY_VALUE(boxMon->otId, boxMon->personality); + bool32 isShiny; + SET8(isShiny); + boxMon->shinyModifier = (shinyValue < SHINY_ODDS) ^ isShiny; break; } + case MON_DATA_HIDDEN_NATURE: + { + u32 nature = GetNatureFromPersonality(boxMon->personality); + u32 hiddenNature; + SET8(hiddenNature); + boxMon->hiddenNatureModifier = nature ^ hiddenNature; + break; + } + } } if (field > MON_DATA_ENCRYPT_SEPARATOR) @@ -3764,6 +3995,18 @@ u8 GetNatureFromPersonality(u32 personality) return personality % NUM_NATURES; } +static u32 GetGMaxTargetSpecies(u32 species) +{ + const struct FormChange *formChanges = GetSpeciesFormChanges(species); + u32 i; + for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++) + { + if (formChanges[i].method == FORM_CHANGE_BATTLE_GIGANTAMAX) + return formChanges[i].targetSpecies; + } + return SPECIES_NONE; +} + u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, struct Pokemon *tradePartner) { int i, j; @@ -3776,6 +4019,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); u16 upperPersonality = personality >> 16; u32 holdEffect, currentMap, partnerSpecies, partnerHeldItem, partnerHoldEffect; + bool32 consumeItem = FALSE; const struct Evolution *evolutions = GetSpeciesEvolutions(species); if (evolutions == NULL) @@ -3848,17 +4092,15 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s case EVO_ITEM_HOLD_NIGHT: if (GetTimeOfDay() == TIME_NIGHT && heldItem == evolutions[i].param) { - heldItem = ITEM_NONE; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); targetSpecies = evolutions[i].targetSpecies; + consumeItem = TRUE; } break; case EVO_ITEM_HOLD_DAY: if (GetTimeOfDay() != TIME_NIGHT && heldItem == evolutions[i].param) { - heldItem = ITEM_NONE; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); targetSpecies = evolutions[i].targetSpecies; + consumeItem = TRUE; } break; case EVO_LEVEL_DUSK: @@ -4037,9 +4279,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s case EVO_ITEM_HOLD: if (heldItem == evolutions[i].param) { - heldItem = 0; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); targetSpecies = evolutions[i].targetSpecies; + consumeItem = TRUE; } break; } @@ -4059,9 +4300,8 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s case EVO_TRADE_ITEM: if (evolutions[i].param == heldItem) { - heldItem = ITEM_NONE; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); targetSpecies = evolutions[i].targetSpecies; + consumeItem = TRUE; } break; case EVO_TRADE_SPECIFIC_MON: @@ -4150,6 +4390,22 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s break; } + // Pikachu, Meowth, and Eevee cannot evolve if they have the + // Gigantamax Factor. We assume that is because their evolutions + // do not have a Gigantamax Form. + if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR, NULL) + && GetGMaxTargetSpecies(species) != SPECIES_NONE + && GetGMaxTargetSpecies(targetSpecies) == SPECIES_NONE) + { + return SPECIES_NONE; + } + + if (consumeItem) + { + heldItem = ITEM_NONE; + SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); + } + return targetSpecies; } @@ -5067,20 +5323,17 @@ static void Task_PlayMapChosenOrBattleBGM(u8 taskId) const u32 *GetMonFrontSpritePal(struct Pokemon *mon) { - u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, 0); - u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - return GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality); + u16 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG, NULL); + bool32 isShiny = GetMonData(mon, MON_DATA_IS_SHINY, NULL); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); + return GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality); } -const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality) +const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, bool32 isShiny, u32 personality) { - u32 shinyValue; - species = SanitizeSpeciesId(species); - shinyValue = GET_SHINY_VALUE(otId, personality); - if (shinyValue < SHINY_ODDS) + if (isShiny) { if (gSpeciesInfo[species].shinyPaletteFemale != NULL && IsPersonalityFemale(species, personality)) return gSpeciesInfo[species].shinyPaletteFemale; @@ -5278,18 +5531,7 @@ void SetWildMonHeldItem(void) bool8 IsMonShiny(struct Pokemon *mon) { - u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - return IsShinyOtIdPersonality(otId, personality); -} - -bool8 IsShinyOtIdPersonality(u32 otId, u32 personality) -{ - bool8 retVal = FALSE; - u32 shinyValue = GET_SHINY_VALUE(otId, personality); - if (shinyValue < SHINY_ODDS) - retVal = TRUE; - return retVal; + return GetMonData(mon, MON_DATA_IS_SHINY, NULL); } const u8 *GetTrainerPartnerName(void) @@ -6072,6 +6314,10 @@ void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality) struct PokemonSubstruct3 *old3, *new3; struct BoxPokemon old; + bool32 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY, NULL); + u32 hiddenNature = GetBoxMonData(boxMon, MON_DATA_HIDDEN_NATURE, NULL); + u32 teraType = GetBoxMonData(boxMon, MON_DATA_TERA_TYPE, NULL); + old = *boxMon; old0 = &(GetSubstruct(&old, old.personality, 0)->type0); old1 = &(GetSubstruct(&old, old.personality, 1)->type1); @@ -6091,6 +6337,36 @@ void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality) *new3 = *old3; boxMon->checksum = CalculateBoxMonChecksum(boxMon); EncryptBoxMon(boxMon); + + SetBoxMonData(boxMon, MON_DATA_IS_SHINY, &isShiny); + SetBoxMonData(boxMon, MON_DATA_HIDDEN_NATURE, &hiddenNature); + SetBoxMonData(boxMon, MON_DATA_TERA_TYPE, &teraType); +} + +void HealPokemon(struct Pokemon *mon) +{ + u32 data; + + data = GetMonData(mon, MON_DATA_MAX_HP); + SetMonData(mon, MON_DATA_HP, &data); + + data = STATUS1_NONE; + SetMonData(mon, MON_DATA_STATUS, &data); + + MonRestorePP(mon); +} + +void HealBoxPokemon(struct BoxPokemon *boxMon) +{ + u32 data; + + data = 0; + SetBoxMonData(boxMon, MON_DATA_HP_LOST, &data); + + data = STATUS1_NONE; + SetBoxMonData(boxMon, MON_DATA_STATUS, &data); + + BoxMonRestorePP(boxMon); } u16 GetCryIdBySpecies(u16 species) diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 6ea897c0a672..ecdcbf26d217 100755 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -157,7 +157,8 @@ enum { struct PokemonJump_MonInfo { - u16 species; + u16 isShiny:1; + u16 species:15; u32 otId; u32 personality; }; @@ -894,6 +895,7 @@ static void InitJumpMonInfo(struct PokemonJump_MonInfo *monInfo, struct Pokemon { monInfo->species = GetMonData(mon, MON_DATA_SPECIES); monInfo->otId = GetMonData(mon, MON_DATA_OT_ID); + monInfo->isShiny = GetMonData(mon, MON_DATA_IS_SHINY); monInfo->personality = GetMonData(mon, MON_DATA_PERSONALITY); } @@ -2970,7 +2972,7 @@ static void CreateJumpMonSprite(struct PokemonJumpGfx *jumpGfx, struct PokemonJu spriteSheet.size = MON_PIC_SIZE; LoadSpriteSheet(&spriteSheet); - spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(monInfo->species, monInfo->otId, monInfo->personality); + spritePalette.data = GetMonSpritePalFromSpeciesAndPersonality(monInfo->species, monInfo->isShiny, monInfo->personality); spritePalette.tag = multiplayerId; LoadCompressedSpritePalette(&spritePalette); @@ -4161,7 +4163,8 @@ static void Task_UpdateBonus(u8 taskId) struct MonInfoPacket { u8 id; - u16 species; + u16 isShiny:1; + u16 species:15; u32 personality; u32 otId; }; @@ -4170,6 +4173,7 @@ static void SendPacket_MonInfo(struct PokemonJump_MonInfo *monInfo) { struct MonInfoPacket packet; packet.id = PACKET_MON_INFO, + packet.isShiny = monInfo->isShiny, packet.species = monInfo->species, packet.otId = monInfo->otId, packet.personality = monInfo->personality, @@ -4187,6 +4191,7 @@ static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo * if (packet.id == PACKET_MON_INFO) { monInfo->species = packet.species; + monInfo->isShiny = packet.isShiny; monInfo->otId = packet.otId; monInfo->personality = packet.personality; return TRUE; diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index 817ec51543cf..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 @@ -6414,15 +6414,13 @@ static void SetMovingMonData(u8 boxId, u8 position) static void SetPlacedMonData(u8 boxId, u8 position) { + if (OW_PC_HEAL <= GEN_7) + HealPokemon(&sStorage->movingMon); + if (boxId == TOTAL_BOXES_COUNT) - { gPlayerParty[position] = sStorage->movingMon; - } else - { - BoxMonRestorePP(&sStorage->movingMon.box); SetBoxMonAt(boxId, position, &sStorage->movingMon.box); - } } static void PurgeMonOrBoxMon(u8 boxId, u8 position) @@ -6964,7 +6962,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode) sStorage->displayMonSpecies = GetBoxMonData(pokemon, MON_DATA_SPECIES_OR_EGG); if (sStorage->displayMonSpecies != SPECIES_NONE) { - u32 otId = GetBoxMonData(boxMon, MON_DATA_OT_ID); + bool8 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY); sanityIsBadEgg = GetBoxMonData(boxMon, MON_DATA_SANITY_IS_BAD_EGG); if (sanityIsBadEgg) sStorage->displayMonIsEgg = TRUE; @@ -6977,7 +6975,7 @@ static void SetDisplayMonData(void *pokemon, u8 mode) sStorage->displayMonLevel = GetLevelFromBoxMonExp(boxMon); sStorage->displayMonMarkings = GetBoxMonData(boxMon, MON_DATA_MARKINGS); sStorage->displayMonPersonality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY); - sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(sStorage->displayMonSpecies, otId, sStorage->displayMonPersonality); + sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(sStorage->displayMonSpecies, isShiny, sStorage->displayMonPersonality); gender = GetGenderFromSpeciesAndPersonality(sStorage->displayMonSpecies, sStorage->displayMonPersonality); sStorage->displayMonItemId = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM); } @@ -8653,6 +8651,8 @@ static void MultiMove_SetPlacedMonData(void) u8 boxPosition = (IN_BOX_COLUMNS * i) + sMultiMove->minColumn; for (j = sMultiMove->minColumn; j < columnCount; j++) { + if (OW_PC_HEAL <= GEN_7) + HealBoxPokemon(&sMultiMove->boxMons[monArrayId]); if (GetBoxMonData(&sMultiMove->boxMons[monArrayId], MON_DATA_SANITY_HAS_SPECIES)) SetBoxMonAt(boxId, boxPosition, &sMultiMove->boxMons[monArrayId]); boxPosition++; @@ -10147,12 +10147,12 @@ static void UnkUtil_DmaRun(struct UnkUtilData *data) void UpdateSpeciesSpritePSS(struct BoxPokemon *boxMon) { u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES); - u32 otId = GetBoxMonData(boxMon, MON_DATA_OT_ID); + bool8 isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY); u32 pid = GetBoxMonData(boxMon, MON_DATA_PERSONALITY); // Update front sprite sStorage->displayMonSpecies = species; - sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(species, otId, pid); + sStorage->displayMonPalette = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, pid); if (!sJustOpenedBag) { LoadDisplayMonGfx(species, pid); diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 2ea61ba730da..8502996620f1 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 @@ -141,7 +141,9 @@ static EWRAM_DATA struct PokemonSummaryScreenData { u16 species; // 0x0 u16 species2; // 0x2 - u8 isEgg; // 0x4 + u8 isEgg:1; // 0x4 + u8 isShiny:1; + u8 padding:6; u8 level; // 0x5 u8 ribbonCount; // 0x6 u8 ailment; // 0x7 @@ -168,6 +170,7 @@ static EWRAM_DATA struct PokemonSummaryScreenData u8 sanity; // 0x35 u8 OTName[17]; // 0x36 u32 OTID; // 0x48 + u8 teraType; } summary; u16 bgTilemapBuffers[PSS_PAGE_COUNT][2][0x400]; u8 mode; @@ -177,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; @@ -187,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; @@ -1541,6 +1544,8 @@ static bool8 ExtractMonDataToSummaryStruct(struct Pokemon *mon) break; default: sum->ribbonCount = GetMonData(mon, MON_DATA_RIBBON_COUNT); + sum->teraType = GetMonData(mon, MON_DATA_TERA_TYPE); + sum->isShiny = GetMonData(mon, MON_DATA_IS_SHINY); return TRUE; } sMonSummaryScreen->switchCounter++; @@ -2790,7 +2795,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); @@ -2836,7 +2841,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); @@ -3188,13 +3193,13 @@ static void PrintMonOTID(void) static void PrintMonAbilityName(void) { u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); - PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityNames[ability], 0, 1, 0, 1); + PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilities[ability].name, 0, 1, 0, 1); } static void PrintMonAbilityDescription(void) { u16 ability = GetAbilityBySpecies(sMonSummaryScreen->summary.species, sMonSummaryScreen->summary.abilityNum); - PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilityDescriptionPointers[ability], 0, 17, 0, 0); + PrintTextOnWindow(AddWindowFromTemplateList(sPageInfoTemplate, PSS_DATA_WINDOW_INFO_ABILITY), gAbilities[ability].description, 0, 17, 0, 0); } static void BufferMonTrainerMemo(void) @@ -3938,6 +3943,10 @@ static void SetMonTypeIcons(void) { SetSpriteInvisibility(SPRITE_ARR_ID_TYPE + 1, TRUE); } + if (P_SHOW_TERA_TYPE >= GEN_9) + { + SetTypeSpritePosAndPal(summary->teraType, 200, 48, SPRITE_ARR_ID_TYPE + 2); + } } } @@ -3949,10 +3958,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); @@ -4042,7 +4048,7 @@ static u8 LoadMonGfxAndSprite(struct Pokemon *mon, s16 *state) (*state)++; return 0xFF; case 1: - LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(summary->species2, summary->OTID, summary->pid), summary->species2); + LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(summary->species2, summary->isShiny, summary->pid), summary->species2); SetMultiuseSpriteTemplateToPokemon(summary->species2, B_POSITION_OPPONENT_LEFT); (*state)++; return 0xFF; @@ -4116,7 +4122,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_conditions.c b/src/pokenav_conditions.c index 3f662e6f3e7d..19cfe38b95d5 100644 --- a/src/pokenav_conditions.c +++ b/src/pokenav_conditions.c @@ -522,7 +522,8 @@ static void GetMonConditionGraphData(s16 listId, u8 loadId) static void ConditionGraphDrawMonPic(s16 listId, u8 loadId) { u16 boxId, monId, species; - u32 personality, tid; + u32 personality; + bool8 isShiny; struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); struct PokenavMonList *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); @@ -532,10 +533,10 @@ static void ConditionGraphDrawMonPic(s16 listId, u8 loadId) boxId = monListPtr->monData[listId].boxId; monId = monListPtr->monData[listId].monId; species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES_OR_EGG, NULL); - tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL); + isShiny = GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_SHINY, NULL); personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL); LoadSpecialPokePic(menu->monPicGfx[loadId], species, personality, TRUE); - LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]); + LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), menu->monPal[loadId]); } u16 GetMonListCount(void) 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/pokenav_ribbons_summary.c b/src/pokenav_ribbons_summary.c index f2e589e56d45..1ff55dc187c6 100644 --- a/src/pokenav_ribbons_summary.c +++ b/src/pokenav_ribbons_summary.c @@ -401,7 +401,7 @@ static void GetMonNicknameLevelGender(u8 *nick, u8 *level, u8 *gender) StringGet_Nickname(nick); } -static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *otId) +static void GetMonSpeciesPersonalityShiny(u16 *species, u32 *personality, bool8 *isShiny) { struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST); struct PokenavMonList *mons = list->monList; @@ -413,7 +413,7 @@ static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *ot struct Pokemon *mon = &gPlayerParty[monInfo->monId]; *species = GetMonData(mon, MON_DATA_SPECIES); *personality = GetMonData(mon, MON_DATA_PERSONALITY); - *otId = GetMonData(mon, MON_DATA_OT_ID); + *isShiny = GetMonData(mon, MON_DATA_IS_SHINY); } else { @@ -421,7 +421,7 @@ static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *ot struct BoxPokemon *boxMon = GetBoxedMonPtr(monInfo->boxId, monInfo->monId); *species = GetBoxMonData(boxMon, MON_DATA_SPECIES); *personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY); - *otId = GetBoxMonData(boxMon, MON_DATA_OT_ID); + *isShiny = GetBoxMonData(boxMon, MON_DATA_IS_SHINY); } } @@ -941,9 +941,10 @@ static void PrintRibbonsMonListIndex(struct Pokenav_RibbonsSummaryMenu *menu) static void ResetSpritesAndDrawMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu) { u16 species; - u32 personality, otId; + u32 personality; + bool8 isShiny; - GetMonSpeciesPersonalityOtId(&species, &personality, &otId); + GetMonSpeciesPersonalityShiny(&species, &personality, &isShiny); ResetAllPicSprites(); menu->monSpriteId = DrawRibbonsMonFrontPic(MON_SPRITE_X_ON, MON_SPRITE_Y); PokenavFillPalette(15, 0); @@ -960,10 +961,11 @@ static void DestroyRibbonsMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu) static u16 DrawRibbonsMonFrontPic(s32 x, s32 y) { u16 species, spriteId; - u32 personality, otId; + u32 personality; + bool8 isShiny; - GetMonSpeciesPersonalityOtId(&species, &personality, &otId); - spriteId = CreateMonPicSprite(species, otId, personality, TRUE, MON_SPRITE_X_ON, MON_SPRITE_Y, 15, TAG_NONE); + GetMonSpeciesPersonalityShiny(&species, &personality, &isShiny); + spriteId = CreateMonPicSprite(species, isShiny, personality, TRUE, MON_SPRITE_X_ON, MON_SPRITE_Y, 15, TAG_NONE); gSprites[spriteId].oam.priority = 0; return spriteId; } diff --git a/src/recorded_battle.c b/src/recorded_battle.c index 1ba62b283712..2ac33a08a0a1 100644 --- a/src/recorded_battle.c +++ b/src/recorded_battle.c @@ -87,7 +87,7 @@ void RecordedBattle_Init(u8 mode) for (j = 0; j < BATTLER_RECORD_SIZE; j++) sBattleRecords[i][j] = 0xFF; sBattleFlags = gBattleTypeFlags; - sAI_Scripts = gBattleResources->ai->aiFlags; + sAI_Scripts = gBattleResources->ai->aiFlags[B_POSITION_OPPONENT_LEFT]; } } } diff --git a/src/rom_header_gf.c b/src/rom_header_gf.c index 919c8c54193e..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 @@ -151,8 +151,8 @@ static const struct GFRomHeader sGFRomHeader = { .externalEventDataOffset = offsetof(struct SaveBlock1, externalEventData), .unk18 = 0x00000000, .speciesInfo = gSpeciesInfo, - .abilityNames = gAbilityNames, - .abilityDescriptions = gAbilityDescriptionPointers, + //.abilityNames = gAbilityNames, //handled in gAbilities + //.abilityDescriptions = gAbilityDescriptionPointers, //handled in gAbilities .items = gItems, .moves = gBattleMoves, .ballGfx = gBallSpriteSheets, diff --git a/src/rom_header_rhh.c b/src/rom_header_rhh.c index 2e141670a744..40c05e4372c6 100644 --- a/src/rom_header_rhh.c +++ b/src/rom_header_rhh.c @@ -1,5 +1,8 @@ #include "global.h" +#include "constants/abilities.h" #include "constants/expansion.h" +#include "constants/moves.h" +#include "constants/species.h" // Similar to the GF ROM header, this struct allows external programs to // detect details about Expansion. @@ -14,6 +17,10 @@ struct RHHRomHeader /*0x07*/ u8 expansionVersionMinor; /*0x08*/ u8 expansionVersionPatch; /*0x09*/ u8 expansionVersionFlags; + /*0x0C*/ u32 movesCount; + /*0x10*/ u32 numSpecies; + /*0x14*/ u32 abilitiesCount; + /*0x18*/ const struct Ability *abilities; }; static const struct RHHRomHeader sRHHRomHeader = @@ -23,4 +30,8 @@ static const struct RHHRomHeader sRHHRomHeader = .expansionVersionMinor = EXPANSION_VERSION_MINOR, .expansionVersionPatch = EXPANSION_VERSION_PATCH, .expansionVersionFlags = (EXPANSION_TAGGED_RELEASE << 0), + .movesCount = MOVES_COUNT, + .numSpecies = NUM_SPECIES, + .abilitiesCount = ABILITIES_COUNT, + .abilities = gAbilities, }; 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 ca455d544db5..2f3c29f2a747 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -16,6 +16,7 @@ #include "party_menu.h" #include "pokedex.h" #include "pokemon.h" +#include "pokemon_storage_system.h" #include "random.h" #include "script.h" #include "sprite.h" @@ -27,35 +28,30 @@ static void CB2_ReturnFromChooseHalfParty(void); static void CB2_ReturnFromChooseBattleFrontierParty(void); +static void HealPlayerBoxes(void); void HealPlayerParty(void) { - u8 i, j; - u8 ppBonuses; - u8 arg[4]; + u32 i; + for (i = 0; i < gPlayerPartyCount; i++) + HealPokemon(&gPlayerParty[i]); + if (OW_PC_HEAL >= GEN_8) + HealPlayerBoxes(); +} + +static void HealPlayerBoxes(void) +{ + int boxId, boxPosition; + struct BoxPokemon *boxMon; - // restore HP. - for(i = 0; i < gPlayerPartyCount; i++) + for (boxId = 0; boxId < TOTAL_BOXES_COUNT; boxId++) { - u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP); - arg[0] = maxHP; - arg[1] = maxHP >> 8; - SetMonData(&gPlayerParty[i], MON_DATA_HP, arg); - ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES); - - // restore PP. - for(j = 0; j < MAX_MON_MOVES; j++) + for (boxPosition = 0; boxPosition < IN_BOX_COUNT; boxPosition++) { - arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j); - SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg); + boxMon = &gPokemonStoragePtr->boxes[boxId][boxPosition]; + if (GetBoxMonData(boxMon, MON_DATA_SANITY_HAS_SPECIES)) + HealBoxPokemon(boxMon); } - - // since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData. - arg[0] = 0; - arg[1] = 0; - arg[2] = 0; - arg[3] = 0; - SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg); } } @@ -260,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 @@ -273,3 +269,72 @@ void ReducePlayerPartyToSelectedMons(void) CalculatePlayerPartyCount(); } + +void CanHyperTrain(struct ScriptContext *ctx) +{ + u32 stat = ScriptReadByte(ctx); + u32 partyIndex = VarGet(ScriptReadHalfword(ctx)); + if (stat < NUM_STATS + && partyIndex < PARTY_SIZE + && !GetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat) + && GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV + stat) < MAX_PER_STAT_IVS) + { + gSpecialVar_Result = TRUE; + } + else + { + gSpecialVar_Result = FALSE; + } +} + +void HyperTrain(struct ScriptContext *ctx) +{ + u32 stat = ScriptReadByte(ctx); + u32 partyIndex = VarGet(ScriptReadHalfword(ctx)); + if (stat < NUM_STATS && partyIndex < PARTY_SIZE) + { + bool32 data = TRUE; + SetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat, &data); + CalculateMonStats(&gPlayerParty[partyIndex]); + } +} + +void HasGigantamaxFactor(struct ScriptContext *ctx) +{ + u32 partyIndex = VarGet(ScriptReadHalfword(ctx)); + if (partyIndex < PARTY_SIZE) + gSpecialVar_Result = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR); + else + gSpecialVar_Result = FALSE; +} + +static const u16 sGigantaxFactorLockedSpecies[] = +{ + SPECIES_MELMETAL, +}; + +void ToggleGigantamaxFactor(struct ScriptContext *ctx) +{ + u32 i; + u32 partyIndex = VarGet(ScriptReadHalfword(ctx)); + u32 species; + + gSpecialVar_Result = FALSE; + + if (partyIndex < PARTY_SIZE) + { + bool32 gigantamaxFactor; + + species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES); + for (i = 0; i < ARRAY_COUNT(sGigantaxFactorLockedSpecies); i++) + { + if (species == sGigantaxFactorLockedSpecies[i]) + return; + } + + gigantamaxFactor = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR); + gigantamaxFactor = !gigantamaxFactor; + SetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR, &gigantamaxFactor); + gSpecialVar_Result = TRUE; + } +} 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 3097f87f7331..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; @@ -630,14 +630,14 @@ static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y) { u8 spriteId; - spriteId = CreateMonPicSprite_Affine(species, SHINY_ODDS, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE); + spriteId = CreateMonPicSprite_Affine(species, FALSE, 0, MON_PIC_AFFINE_FRONT, x, y, 14, TAG_NONE); gSprites[spriteId].oam.priority = 0; return spriteId; } 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 5e0564a1ffc8..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)) @@ -4842,7 +4842,7 @@ static void CheckPartnersMonForRibbons(void) { u8 i; u8 numRibbons = 0; - for (i = 0; i < (MON_DATA_UNUSED_RIBBONS - MON_DATA_CHAMPION_RIBBON); i++) + for (i = 0; i < (MON_DATA_WORLD_RIBBON - MON_DATA_CHAMPION_RIBBON + 1); i++) numRibbons += GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_CHAMPION_RIBBON + i); if (numRibbons != 0) diff --git a/src/trainer_pokemon_sprites.c b/src/trainer_pokemon_sprites.c index 6ffbc836d7a4..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) @@ -73,19 +73,19 @@ static bool16 DecompressPic(u16 species, u32 personality, bool8 isFrontPic, u8 * return FALSE; } -static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +static void LoadPicPaletteByTagOrSlot(u16 species, bool8 isShiny, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) { if (!isTrainer) { if (paletteTag == TAG_NONE) { sCreatingSpriteTemplate.paletteTag = TAG_NONE; - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), OBJ_PLTT_ID(paletteSlot), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), OBJ_PLTT_ID(paletteSlot), PLTT_SIZE_4BPP); } else { sCreatingSpriteTemplate.paletteTag = paletteTag; - LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), species); + LoadCompressedSpritePaletteWithTag(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), species); } } else @@ -103,10 +103,10 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 } } -static void LoadPicPaletteBySlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer) +static void LoadPicPaletteBySlot(u16 species, bool8 isShiny, u32 personality, u8 paletteSlot, bool8 isTrainer) { if (!isTrainer) - LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), PLTT_ID(paletteSlot), PLTT_SIZE_4BPP); + LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personality), PLTT_ID(paletteSlot), PLTT_SIZE_4BPP); else LoadCompressedPalette(gTrainerSprites[species].palette.data, PLTT_ID(paletteSlot), PLTT_SIZE_4BPP); } @@ -119,7 +119,7 @@ static void AssignSpriteAnimsTable(bool8 isTrainer) sCreatingSpriteTemplate.anims = gTrainerSprites[0].animation; } -static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) +static u16 CreatePicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer) { u8 i; u8 *framePics; @@ -161,7 +161,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront sCreatingSpriteTemplate.images = images; sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; sCreatingSpriteTemplate.callback = DummyPicSpriteCallback; - LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, isTrainer); + LoadPicPaletteByTagOrSlot(species, isShiny, personality, paletteSlot, paletteTag, isTrainer); spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0); if (paletteTag == TAG_NONE) gSprites[spriteId].oam.paletteNum = paletteSlot; @@ -173,7 +173,7 @@ static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFront return spriteId; } -u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) +u16 CreateMonPicSprite_Affine(u16 species, bool8 isShiny, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) { u8 *framePics; struct SpriteFrameImage *images; @@ -239,7 +239,7 @@ u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable; } sCreatingSpriteTemplate.callback = DummyPicSpriteCallback; - LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, FALSE); + LoadPicPaletteByTagOrSlot(species, isShiny, personality, paletteSlot, paletteTag, FALSE); spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0); if (paletteTag == TAG_NONE) gSprites[spriteId].oam.paletteNum = paletteSlot; @@ -276,16 +276,16 @@ static u16 FreeAndDestroyPicSpriteInternal(u16 spriteId) return 0; } -static u16 LoadPicSpriteInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) +static u16 LoadPicSpriteInWindow(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer) { if (DecompressPic(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE)) return 0xFFFF; - LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer); + LoadPicPaletteBySlot(species, isShiny, personality, paletteSlot, isTrainer); return 0; } -static u16 CreateTrainerCardSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer) +static u16 CreateTrainerCardSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer) { u8 *framePics; @@ -293,16 +293,16 @@ static u16 CreateTrainerCardSprite(u16 species, u32 otId, u32 personality, bool8 if (framePics && !DecompressPic(species, personality, isFrontPic, framePics, isTrainer)) { BlitBitmapRectToWindow(windowId, framePics, 0, 0, TRAINER_PIC_WIDTH, TRAINER_PIC_HEIGHT, destX, destY, TRAINER_PIC_WIDTH, TRAINER_PIC_HEIGHT); - LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer); + LoadPicPaletteBySlot(species, isShiny, personality, paletteSlot, isTrainer); Free(framePics); return 0; } return 0xFFFF; } -u16 CreateMonPicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) +u16 CreateMonPicSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) { - return CreatePicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE); + return CreatePicSprite(species, isShiny, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE); } u16 FreeAndDestroyMonPicSprite(u16 spriteId) @@ -310,20 +310,20 @@ u16 FreeAndDestroyMonPicSprite(u16 spriteId) return FreeAndDestroyPicSpriteInternal(spriteId); } -static u16 UNUSED LoadMonPicInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId) +static u16 UNUSED LoadMonPicInWindow(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId) { - return LoadPicSpriteInWindow(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE); + return LoadPicSpriteInWindow(species, isShiny, personality, isFrontPic, paletteSlot, windowId, FALSE); } // Unused, FRLG only -u16 CreateTrainerCardMonIconSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId) +u16 CreateTrainerCardMonIconSprite(u16 species, bool8 isShiny, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId) { - return CreateTrainerCardSprite(species, otId, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE); + return CreateTrainerCardSprite(species, isShiny, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE); } u16 CreateTrainerPicSprite(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag) { - return CreatePicSprite(species, 0, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE); + return CreatePicSprite(species, FALSE, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE); } u16 FreeAndDestroyTrainerPicSprite(u16 spriteId) @@ -333,12 +333,12 @@ u16 FreeAndDestroyTrainerPicSprite(u16 spriteId) static u16 UNUSED LoadTrainerPicInWindow(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId) { - return LoadPicSpriteInWindow(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE); + return LoadPicSpriteInWindow(species, FALSE, 0, isFrontPic, paletteSlot, windowId, TRUE); } u16 CreateTrainerCardTrainerPicSprite(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId) { - return CreateTrainerCardSprite(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE); + return CreateTrainerCardSprite(species, FALSE, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE); } u16 PlayerGenderToFrontTrainerPicId_Debug(u8 gender, bool8 getClass) diff --git a/src/tv.c b/src/tv.c index 306d0fc9e3f3..e89f6a9145cc 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1956,7 +1956,6 @@ void AlertTVThatPlayerPlayedRoulette(u16 nCoinsSpent) static void SecretBaseVisit_CalculateDecorationData(TVShow *show) { u8 i, j; - u16 k; u8 n; u8 decoration; @@ -2002,12 +2001,7 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show) break; default: // More than 1 decoration, randomize the full list - for (k = 0; k < n * n; k++) - { - decoration = Random() % n; - j = Random() % n; - SWAP(sTV_DecorationsBuffer[decoration], sTV_DecorationsBuffer[j], i); - } + Shuffle(sTV_DecorationsBuffer, n, sizeof(sTV_DecorationsBuffer[0])); // Pick the first decorations in the randomized list to talk about on the show for (i = 0; i < show->secretBaseVisit.numDecorations; i++) @@ -6212,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 13b92136f869..474c5ef560fe 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -385,7 +385,6 @@ static u16 GetCurrentMapWildMonHeaderId(void) u8 PickWildMonNature(void) { u8 i; - u8 j; struct Pokeblock *safariPokeblock; u8 natures[NUM_NATURES]; @@ -396,17 +395,7 @@ u8 PickWildMonNature(void) { for (i = 0; i < NUM_NATURES; i++) natures[i] = i; - for (i = 0; i < NUM_NATURES - 1; i++) - { - for (j = i + 1; j < NUM_NATURES; j++) - { - if (Random() & 1) - { - u8 temp; - SWAP(natures[i], natures[j], temp); - } - } - } + Shuffle(natures, NUM_NATURES, sizeof(natures[0])); for (i = 0; i < NUM_NATURES; i++) { if (PokeblockGetGain(natures[i], safariPokeblock) > 0) @@ -414,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 @@ -913,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/contrary.c b/test/battle/ability/contrary.c index 03af17bdc070..af71b211c8b3 100644 --- a/test/battle/ability/contrary.c +++ b/test/battle/ability/contrary.c @@ -187,3 +187,37 @@ SINGLE_BATTLE_TEST("Contrary raises a stat after using a move which would normal EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.125), results[0].damage); } } + +SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normally raise it: Belly Drum", s16 damageBefore, s16 damageAfter) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_CONTRARY; } + PARAMETRIZE { ability = ABILITY_TANGLED_FEET; } + GIVEN { + ASSUME(gBattleMoves[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SPINDA) { Ability(ability); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(opponent, MOVE_BELLY_DRUM); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + MESSAGE("Foe Spinda used Tackle!"); + HP_BAR(player, captureDamage: &results[i].damageBefore); + + if (ability == ABILITY_CONTRARY) { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Spinda cut its own HP and maximized ATTACK!"); //Message stays the same + } + else { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Spinda cut its own HP and maximized ATTACK!"); + } + + HP_BAR(player, captureDamage: &results[i].damageAfter); + } + FINALLY { + EXPECT_MUL_EQ(results[0].damageBefore, UQ_4_12(0.25), results[0].damageAfter); + EXPECT_MUL_EQ(results[1].damageBefore, UQ_4_12(4.0), results[1].damageAfter); + } +} 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/ai_check_viability.c b/test/battle/ai_check_viability.c index 4666eca7cb05..2f229e3aca6d 100644 --- a/test/battle/ai_check_viability.c +++ b/test/battle/ai_check_viability.c @@ -177,15 +177,15 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves with secondary effect that have a 100% c AI_LOG; ASSUME(gBattleMoves[MOVE_SHADOW_BALL].effect == EFFECT_SPECIAL_DEFENSE_DOWN_HIT); ASSUME(gBattleMoves[MOVE_SHADOW_BALL].secondaryEffectChance == 20); - ASSUME(gBattleMoves[MOVE_LUSTER_PURGE].effect == EFFECT_SPECIAL_DEFENSE_DOWN_HIT); - ASSUME(gBattleMoves[MOVE_LUSTER_PURGE].secondaryEffectChance == 50); + ASSUME(gBattleMoves[MOVE_OCTAZOOKA].effect == EFFECT_ACCURACY_DOWN_HIT); + ASSUME(gBattleMoves[MOVE_OCTAZOOKA].secondaryEffectChance == 50); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_REGICE); - OPPONENT(SPECIES_REGIROCK) { Ability(ability); Moves(MOVE_SHADOW_BALL, MOVE_LUSTER_PURGE); } + OPPONENT(SPECIES_REGIROCK) { Ability(ability); Moves(MOVE_SHADOW_BALL, MOVE_OCTAZOOKA); } } WHEN { if (ability == ABILITY_NONE) TURN { EXPECT_MOVE(opponent, MOVE_SHADOW_BALL); } else - TURN { EXPECT_MOVES(opponent, MOVE_LUSTER_PURGE); } + TURN { EXPECT_MOVES(opponent, MOVE_OCTAZOOKA); } } } 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/ally_switch.c b/test/battle/move_effect/ally_switch.c index 3271fd0cbe9b..bbfb774539be 100644 --- a/test/battle/move_effect/ally_switch.c +++ b/test/battle/move_effect/ally_switch.c @@ -207,3 +207,24 @@ DOUBLE_BATTLE_TEST("Ally Switch increases the Protect-like moves counter") EXPECT(gDisableStructs[B_POSITION_PLAYER_RIGHT].protectUses == 1); } } + +DOUBLE_BATTLE_TEST("Ally Switch works if ally used two-turn move like Dig") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerRight, MOVE_DIG, target:opponentRight); } + TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); SKIP_TURN(playerRight); } + } SCENE { + MESSAGE("Wynaut used Dig!"); + MESSAGE("Wobbuffet used Ally Switch!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ALLY_SWITCH, playerLeft); + MESSAGE("Wobbuffet and Wynaut switched places!"); + NOT MESSAGE("Wynaut used -!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DIG); + HP_BAR(opponentRight); + } +} diff --git a/test/battle/move_effect/belly_drum.c b/test/battle/move_effect/belly_drum.c new file mode 100644 index 000000000000..b3f02f7a1911 --- /dev/null +++ b/test/battle/move_effect/belly_drum.c @@ -0,0 +1,92 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); +} + +SINGLE_BATTLE_TEST("Belly Drum cuts the user's HP in half") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BELLY_DRUM); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + HP_BAR(player, hp: maxHP / 2); + } +} + +SINGLE_BATTLE_TEST("Belly Drum maximizes the user's Attack stat", s16 damage) +{ + bool32 raiseAttack; + PARAMETRIZE { raiseAttack = FALSE; } + PARAMETRIZE { raiseAttack = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].category == BATTLE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseAttack) TURN { MOVE(player, MOVE_BELLY_DRUM); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (raiseAttack) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet cut its own HP and maximized ATTACK!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(4), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Belly Drum fails if user's current HP is half or less than half its maximum") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(50);} + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BELLY_DRUM); } + } SCENE { + MESSAGE("But it failed!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); + HP_BAR(player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } + } +} + +SINGLE_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SWORDS_DANCE); } + TURN { MOVE(player, MOVE_SWORDS_DANCE); } + TURN { MOVE(player, MOVE_SWORDS_DANCE); } + TURN { MOVE(player, MOVE_BELLY_DRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Attack sharply rose!"); + + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Attack sharply rose!"); + + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Attack sharply rose!"); + + MESSAGE("But it failed!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); + HP_BAR(player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } + } +} 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/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/fillet_away.c b/test/battle/move_effect/fillet_away.c new file mode 100644 index 000000000000..ea403e16d6dc --- /dev/null +++ b/test/battle/move_effect/fillet_away.c @@ -0,0 +1,58 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_FILLET_AWAY].effect == EFFECT_FILLET_AWAY); +} + +SINGLE_BATTLE_TEST("Fillet Away cuts the user's HP in half") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FILLET_AWAY); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + HP_BAR(player, hp: maxHP / 2); + } +} + +SINGLE_BATTLE_TEST("Fillet Away sharply raises Attack, Sp. Atk, and Speed") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FILLET_AWAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FILLET_AWAY, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Attack sharply rose!"); + MESSAGE("Wobbuffet's Sp. Atk sharply rose!"); + MESSAGE("Wobbuffet's Speed sharply rose!"); + HP_BAR(player); + } THEN { + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 2); + EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 2); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2); + } +} + +SINGLE_BATTLE_TEST("Fillet Away fails if user's current HP is half or less than half its maximum") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(50);} + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FILLET_AWAY); } + } SCENE { + MESSAGE("But it failed!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FILLET_AWAY, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + HP_BAR(player); + } + } +} 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/battle/trainer_control.c b/test/battle/trainer_control.c index 810a721fa5af..e3e071745d6a 100644 --- a/test/battle/trainer_control.c +++ b/test/battle/trainer_control.c @@ -27,7 +27,8 @@ static const struct TrainerMon sTestParty1[] = .lvl = 67, .moves = {MOVE_AIR_SLASH, MOVE_BARRIER, MOVE_SOLAR_BEAM, MOVE_EXPLOSION}, .nature = TRAINER_PARTY_NATURE(NATURE_HASTY), - .nickname = COMPOUND_STRING("Bubbles") + .nickname = COMPOUND_STRING("Bubbles"), + .dynamaxLevel = 5, }, { .species = SPECIES_WOBBUFFET, @@ -110,6 +111,9 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon") EXPECT(GetMonGender(&testParty[0]) == MON_FEMALE); EXPECT(GetNature(&testParty[0]) == NATURE_HASTY); + EXPECT_EQ(GetMonData(&testParty[0], MON_DATA_DYNAMAX_LEVEL), 5); + EXPECT_EQ(GetMonData(&testParty[1], MON_DATA_DYNAMAX_LEVEL), 0); + Free(testParty); } diff --git a/test/dynamax.c b/test/dynamax.c index 69887d6d2f74..0d6ee7217224 100644 --- a/test/dynamax.c +++ b/test/dynamax.c @@ -465,16 +465,19 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Instruct") } } -// TODO: Gigantamax factor SINGLE_BATTLE_TEST("(DYNAMAX) Pokemon with Gigantamax forms change upon Dynamaxing") { + u32 species; + bool32 gigantamaxFactor; + PARAMETRIZE { gigantamaxFactor = FALSE; species = SPECIES_VENUSAUR; } + PARAMETRIZE { gigantamaxFactor = TRUE; species = SPECIES_VENUSAUR_GIGANTAMAX; } GIVEN { - PLAYER(SPECIES_VENUSAUR); + PLAYER(SPECIES_VENUSAUR) { GigantamaxFactor(gigantamaxFactor); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, MOVE_TACKLE, dynamax: TRUE); } } THEN { - EXPECT_EQ(player->species, SPECIES_VENUSAUR_GIGANTAMAX); + EXPECT_EQ(player->species, species); } } @@ -870,7 +873,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_STONESURGE].argument == MAX_EFFECT_STEALTH_ROCK); - PLAYER(SPECIES_DREDNAW); + PLAYER(SPECIES_DREDNAW) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -890,7 +893,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Steelsurge sets up sharp steel") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_STEELSURGE].argument == MAX_EFFECT_STEELSURGE); - PLAYER(SPECIES_COPPERAJAH); + PLAYER(SPECIES_COPPERAJAH) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_HATTERENE); } WHEN { @@ -921,7 +924,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili PARAMETRIZE { move = MOVE_HYDRO_CANNON; } GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_HYDROSNIPE].argument == MAX_EFFECT_FIXED_POWER); - PLAYER(SPECIES_INTELEON); + PLAYER(SPECIES_INTELEON) { GigantamaxFactor(TRUE); } OPPONENT(SPECIES_ARCTOVISH) { Ability(ABILITY_WATER_ABSORB); } } WHEN { TURN { MOVE(player, move, dynamax: TRUE); } @@ -937,7 +940,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Volt Crash paralyzes both opponents") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_VOLT_CRASH].argument == MAX_EFFECT_PARALYZE_FOES); - PLAYER(SPECIES_PIKACHU); + PLAYER(SPECIES_PIKACHU) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_PICHU); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); @@ -964,7 +967,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = STATUS1_POISON; } GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES); - PLAYER(SPECIES_TOXTRICITY); + PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_TOXEL); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); @@ -1001,7 +1004,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock chooses statuses before consideri { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES); - PLAYER(SPECIES_TOXTRICITY); + PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_TOXEL); OPPONENT(SPECIES_GARBODOR); OPPONENT(SPECIES_TRUBBISH); @@ -1034,7 +1037,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = STATUS1_SLEEP; } GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_BEFUDDLE].argument == MAX_EFFECT_EFFECT_SPORE_FOES); - PLAYER(SPECIES_BUTTERFREE); + PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_CATERPIE); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1078,7 +1081,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and genera { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_GOLD_RUSH].argument == MAX_EFFECT_CONFUSE_FOES_PAY_DAY); - PLAYER(SPECIES_MEOWTH); + PLAYER(SPECIES_MEOWTH) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_PERSIAN); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1098,7 +1101,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_SMITE].argument == MAX_EFFECT_CONFUSE_FOES); - PLAYER(SPECIES_HATTERENE); + PLAYER(SPECIES_HATTERENE) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_HATENNA); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1117,7 +1120,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possibl { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_CUDDLE].argument == MAX_EFFECT_INFATUATE_FOES); - PLAYER(SPECIES_EEVEE) { Gender(MON_MALE); } + PLAYER(SPECIES_EEVEE) { Gender(MON_MALE); GigantamaxFactor(TRUE); } PLAYER(SPECIES_EEVEE); OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); } OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_MALE); } @@ -1138,7 +1141,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Terror traps both opponents") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_TERROR].argument == MAX_EFFECT_MEAN_LOOK); - PLAYER(SPECIES_GENGAR); + PLAYER(SPECIES_GENGAR) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_GASTLY); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1157,7 +1160,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Meltdown torments both opponents for 3 turns { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_MELTDOWN].argument == MAX_EFFECT_TORMENT_FOES); - PLAYER(SPECIES_MELMETAL); + PLAYER(SPECIES_MELMETAL) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_MELTAN); OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SPLASH, MOVE_CELEBRATE); } OPPONENT(SPECIES_WYNAUT) { Moves(MOVE_SPLASH, MOVE_CELEBRATE); } @@ -1194,7 +1197,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Wildfire sets a field effect that damages no s16 damage; GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_WILDFIRE].argument == MAX_EFFECT_WILDFIRE); - PLAYER(SPECIES_CHARIZARD); + PLAYER(SPECIES_CHARIZARD) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_CHARMANDER); OPPONENT(SPECIES_WOBBUFFET) { HP(600); MaxHP(600); } OPPONENT(SPECIES_WYNAUT); @@ -1240,7 +1243,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of t PASSES_RANDOMLY(1, 2, RNG_G_MAX_REPLENISH); GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_REPLENISH].argument == MAX_EFFECT_RECYCLE_BERRIES); - PLAYER(SPECIES_SNORLAX) { Item(ITEM_APICOT_BERRY); } + PLAYER(SPECIES_SNORLAX) { Item(ITEM_APICOT_BERRY); GigantamaxFactor(TRUE); } PLAYER(SPECIES_MUNCHLAX) { Item(ITEM_APICOT_BERRY); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); } @@ -1268,7 +1271,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Snooze makes only the target drowsy") PASSES_RANDOMLY(1, 2, RNG_G_MAX_SNOOZE); GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_SNOOZE].argument == MAX_EFFECT_YAWN_FOE); - PLAYER(SPECIES_GRIMMSNARL); + PLAYER(SPECIES_GRIMMSNARL) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_IMPIDIMP); OPPONENT(SPECIES_BLISSEY); OPPONENT(SPECIES_CHANSEY); @@ -1291,7 +1294,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") s16 damage1, damage2; GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_FINALE].argument == MAX_EFFECT_HEAL_TEAM); - PLAYER(SPECIES_ALCREMIE) { HP(1); } + PLAYER(SPECIES_ALCREMIE) { HP(1); GigantamaxFactor(TRUE); } PLAYER(SPECIES_MILCERY) { HP(1); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1311,7 +1314,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_SWEETNESS].argument == MAX_EFFECT_AROMATHERAPY); - PLAYER(SPECIES_APPLETUN) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_APPLETUN) { Status1(STATUS1_POISON); GigantamaxFactor(TRUE); } PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1331,7 +1334,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Centiferno traps both opponents in Fire Spin { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_CENTIFERNO].argument == MAX_EFFECT_FIRE_SPIN_FOES); - PLAYER(SPECIES_CENTISKORCH); + PLAYER(SPECIES_CENTISKORCH) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_SIZZLIPEDE); PLAYER(SPECIES_SIZZLIPEDE); OPPONENT(SPECIES_WOBBUFFET); @@ -1360,7 +1363,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Chi Strike boosts allies' crit chance") GIVEN { ASSUME(B_CRIT_CHANCE >= GEN_6); ASSUME(gBattleMoves[MOVE_G_MAX_CHI_STRIKE].argument == MAX_EFFECT_CRIT_PLUS); - PLAYER(SPECIES_MACHAMP); + PLAYER(SPECIES_MACHAMP) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_MACHOP); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -1389,7 +1392,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Depletion takes away 2 PP from the target's { GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_DEPLETION].argument == MAX_EFFECT_SPITE); - PLAYER(SPECIES_DURALUDON); + PLAYER(SPECIES_DURALUDON) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_WYNAUT); // Dynamax behaves weird with test turn order because stats are recalculated. OPPONENT(SPECIES_SABLEYE) { Ability(ABILITY_PRANKSTER); } @@ -1411,7 +1414,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage" PARAMETRIZE { protect = FALSE; } GIVEN { ASSUME(gBattleMoves[MOVE_G_MAX_ONE_BLOW].argument == MAX_EFFECT_BYPASS_PROTECT); - PLAYER(SPECIES_URSHIFU); + PLAYER(SPECIES_URSHIFU) { GigantamaxFactor(TRUE); } PLAYER(SPECIES_KUBFU); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); diff --git a/test/pokemon.c b/test/pokemon.c new file mode 100644 index 000000000000..05d6ac15e52c --- /dev/null +++ b/test/pokemon.c @@ -0,0 +1,182 @@ +#include "global.h" +#include "battle.h" +#include "event_data.h" +#include "pokemon.h" +#include "test/overworld_script.h" +#include "test/test.h" + +TEST("Nature independent from Hidden Nature") +{ + u32 i, j, nature = 0, hiddenNature = 0; + struct Pokemon mon; + for (i = 0; i < NUM_NATURES; i++) + { + for (j = 0; j < NUM_NATURES; j++) + { + PARAMETRIZE { nature = i; hiddenNature = j; } + } + } + CreateMonWithNature(&mon, SPECIES_WOBBUFFET, 100, 0, nature); + SetMonData(&mon, MON_DATA_HIDDEN_NATURE, &hiddenNature); + EXPECT_EQ(GetNature(&mon), nature); + EXPECT_EQ(GetMonData(&mon, MON_DATA_HIDDEN_NATURE), hiddenNature); +} + +TEST("Terastallization type defaults to primary or secondary type") +{ + u32 i, teraType; + struct Pokemon mon; + for (i = 0; i < 128; i++) PARAMETRIZE {} + CreateMon(&mon, SPECIES_PIDGEY, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + teraType = GetMonData(&mon, MON_DATA_TERA_TYPE); + EXPECT(teraType == gSpeciesInfo[SPECIES_PIDGEY].types[0] + || teraType == gSpeciesInfo[SPECIES_PIDGEY].types[1]); +} + +TEST("Terastallization type can be set to any type") +{ + u32 i, teraType; + struct Pokemon mon; + for (i = 0; i < NUMBER_OF_MON_TYPES; i++) + { + PARAMETRIZE { teraType = i; } + } + CreateMon(&mon, SPECIES_WOBBUFFET, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + SetMonData(&mon, MON_DATA_TERA_TYPE, &teraType); + EXPECT_EQ(teraType, GetMonData(&mon, MON_DATA_TERA_TYPE)); +} + +TEST("Shininess independent from PID and OTID") +{ + u32 pid, otId, data; + bool32 isShiny; + struct Pokemon mon; + PARAMETRIZE { pid = 0; otId = 0; } + CreateMon(&mon, SPECIES_WOBBUFFET, 100, 0, TRUE, pid, OT_ID_PRESET, otId); + isShiny = IsMonShiny(&mon); + data = !isShiny; + SetMonData(&mon, MON_DATA_IS_SHINY, &data); + EXPECT_EQ(pid, GetMonData(&mon, MON_DATA_PERSONALITY)); + EXPECT_EQ(otId, GetMonData(&mon, MON_DATA_OT_ID)); + EXPECT_EQ(!isShiny, GetMonData(&mon, MON_DATA_IS_SHINY)); +} + +TEST("Hyper Training increases stats without affecting IVs") +{ + u32 data, hp, atk, def, speed, spatk, spdef; + struct Pokemon mon; + CreateMon(&mon, SPECIES_WOBBUFFET, 100, 3, TRUE, 0, OT_ID_PRESET, 0); + + hp = GetMonData(&mon, MON_DATA_HP); + atk = GetMonData(&mon, MON_DATA_ATK); + def = GetMonData(&mon, MON_DATA_DEF); + speed = GetMonData(&mon, MON_DATA_SPEED); + spatk = GetMonData(&mon, MON_DATA_SPATK); + spdef = GetMonData(&mon, MON_DATA_SPDEF); + + data = TRUE; + SetMonData(&mon, MON_DATA_HYPER_TRAINED_HP, &data); + SetMonData(&mon, MON_DATA_HYPER_TRAINED_ATK, &data); + SetMonData(&mon, MON_DATA_HYPER_TRAINED_DEF, &data); + SetMonData(&mon, MON_DATA_HYPER_TRAINED_SPEED, &data); + SetMonData(&mon, MON_DATA_HYPER_TRAINED_SPATK, &data); + SetMonData(&mon, MON_DATA_HYPER_TRAINED_SPDEF, &data); + CalculateMonStats(&mon); + + EXPECT_EQ(GetMonData(&mon, MON_DATA_HP_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_ATK_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_DEF_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_SPEED_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_SPATK_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_SPDEF_IV), 3); + EXPECT_EQ(GetMonData(&mon, MON_DATA_SPEED_IV), 3); + + EXPECT_EQ(hp - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_HP)); + EXPECT_EQ(atk - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_ATK)); + EXPECT_EQ(def - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_DEF)); + EXPECT_EQ(speed - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_SPEED)); + EXPECT_EQ(spatk - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_SPATK)); + EXPECT_EQ(spdef - 3 + MAX_PER_STAT_IVS, GetMonData(&mon, MON_DATA_SPDEF)); +} + +TEST("Status1 round-trips through BoxPokemon") +{ + u32 status1; + struct Pokemon mon1, mon2; + PARAMETRIZE { status1 = STATUS1_NONE; } + PARAMETRIZE { status1 = STATUS1_SLEEP_TURN(1); } + PARAMETRIZE { status1 = STATUS1_SLEEP_TURN(2); } + PARAMETRIZE { status1 = STATUS1_SLEEP_TURN(3); } + PARAMETRIZE { status1 = STATUS1_SLEEP_TURN(4); } + PARAMETRIZE { status1 = STATUS1_SLEEP_TURN(5); } + PARAMETRIZE { status1 = STATUS1_POISON; } + PARAMETRIZE { status1 = STATUS1_BURN; } + PARAMETRIZE { status1 = STATUS1_FREEZE; } + PARAMETRIZE { status1 = STATUS1_PARALYSIS; } + PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } + PARAMETRIZE { status1 = STATUS1_FROSTBITE; } + CreateMon(&mon1, SPECIES_WOBBUFFET, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + SetMonData(&mon1, MON_DATA_STATUS, &status1); + BoxMonToMon(&mon1.box, &mon2); + EXPECT_EQ(GetMonData(&mon2, MON_DATA_STATUS), status1); +} + +TEST("canhypertrain/hypertrain affect MON_DATA_HYPER_TRAINED_* and recalculate stats") +{ + u32 atk; + CreateMon(&gPlayerParty[0], SPECIES_WOBBUFFET, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + atk = GetMonData(&gPlayerParty[0], MON_DATA_ATK); + + RUN_OVERWORLD_SCRIPT( + canhypertrain STAT_ATK, 0; + ); + EXPECT(VarGet(VAR_RESULT)); + + RUN_OVERWORLD_SCRIPT( + hypertrain STAT_ATK, 0; + canhypertrain STAT_ATK, 0; + ); + EXPECT(GetMonData(&gPlayerParty[0], MON_DATA_HYPER_TRAINED_ATK)); + EXPECT_EQ(atk + 31, GetMonData(&gPlayerParty[0], MON_DATA_ATK)); + EXPECT(!VarGet(VAR_RESULT)); +} + +TEST("hasgigantamaxfactor/togglegigantamaxfactor affect MON_DATA_GIGANTAMAX_FACTOR") +{ + CreateMon(&gPlayerParty[0], SPECIES_WOBBUFFET, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + + RUN_OVERWORLD_SCRIPT( + hasgigantamaxfactor 0; + ); + EXPECT(!VarGet(VAR_RESULT)); + + RUN_OVERWORLD_SCRIPT( + togglegigantamaxfactor 0; + hasgigantamaxfactor 0; + ); + EXPECT(VarGet(VAR_RESULT)); + EXPECT(GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR)); + + RUN_OVERWORLD_SCRIPT( + togglegigantamaxfactor 0; + hasgigantamaxfactor 0; + ); + EXPECT(!VarGet(VAR_RESULT)); + EXPECT(!GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR)); +} + +TEST("togglegigantamaxfactor fails for Melmetal") +{ + CreateMon(&gPlayerParty[0], SPECIES_MELMETAL, 100, 0, FALSE, 0, OT_ID_PRESET, 0); + + RUN_OVERWORLD_SCRIPT( + hasgigantamaxfactor 0; + ); + EXPECT(!VarGet(VAR_RESULT)); + + RUN_OVERWORLD_SCRIPT( + togglegigantamaxfactor 0; + ); + EXPECT(!VarGet(VAR_RESULT)); + EXPECT(!GetMonData(&gPlayerParty[0], MON_DATA_GIGANTAMAX_FACTOR)); +} diff --git a/test/species.c b/test/species.c index 9ea20638c8da..d412dd005ad5 100644 --- a/test/species.c +++ b/test/species.c @@ -34,6 +34,8 @@ TEST("Form change tables contain only forms in the form species ID table") for (i = 0; formChangeTable[i].method != FORM_CHANGE_TERMINATOR; i++) { + if (formChangeTable[i].targetSpecies == SPECIES_NONE) + continue; for (j = 0; formSpeciesIdTable[j] != FORM_SPECIES_END; j++) { if (formChangeTable[i].targetSpecies == formSpeciesIdTable[j]) diff --git a/test/test_runner.c b/test/test_runner.c index 93d859654acf..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) @@ -398,11 +403,21 @@ static void FunctionTest_TearDown(void *data) FREE_AND_SET_NULL(gFunctionTestRunnerState); } +static bool32 FunctionTest_CheckProgress(void *data) +{ + bool32 madeProgress; + (void)data; + madeProgress = gFunctionTestRunnerState->checkProgressParameter < gFunctionTestRunnerState->runParameter; + gFunctionTestRunnerState->checkProgressParameter = gFunctionTestRunnerState->runParameter; + return madeProgress; +} + const struct TestRunner gFunctionTestRunner = { .setUp = FunctionTest_SetUp, .run = FunctionTest_Run, .tearDown = FunctionTest_TearDown, + .checkProgress = FunctionTest_CheckProgress, }; static void Assumptions_Run(void *data) @@ -652,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; +} diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 1528a3ccf9e4..caccdb2042fe 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -1587,6 +1587,7 @@ static u32 GenerateNature(u32 nature, u32 offset) void ClosePokemon(u32 sourceLine) { s32 i; + u32 data; INVALID_IF(DATA.hasExplicitSpeeds && !(DATA.explicitSpeeds[DATA.currentSide] & (1 << DATA.currentPartyIndex)), "Speed required"); for (i = 0; i < STATE->battlersCount; i++) { @@ -1596,6 +1597,8 @@ void ClosePokemon(u32 sourceLine) INVALID_IF(GetMonData(DATA.currentMon, MON_DATA_HP) == 0, "Battlers cannot be fainted"); } } + data = FALSE; + SetMonData(DATA.currentMon, MON_DATA_IS_SHINY, &data); UpdateMonPersonality(&DATA.currentMon->box, GenerateNature(DATA.nature, DATA.gender % NUM_NATURES) | DATA.gender); DATA.currentMon = NULL; } @@ -1766,10 +1769,34 @@ void Status1_(u32 sourceLine, u32 status1) void OTName_(u32 sourceLine, const u8 *otName) { - INVALID_IF(!DATA.currentMon, "Traded outside of PLAYER/OPPONENT"); + INVALID_IF(!DATA.currentMon, "OTName outside of PLAYER/OPPONENT"); SetMonData(DATA.currentMon, MON_DATA_OT_NAME, &otName); } +void DynamaxLevel_(u32 sourceLine, u32 dynamaxLevel) +{ + INVALID_IF(!DATA.currentMon, "DynamaxLevel outside of PLAYER/OPPONENT"); + SetMonData(DATA.currentMon, MON_DATA_DYNAMAX_LEVEL, &dynamaxLevel); +} + +void GigantamaxFactor_(u32 sourceLine, bool32 gigantamaxFactor) +{ + INVALID_IF(!DATA.currentMon, "GigantamaxFactor outside of PLAYER/OPPONENT"); + SetMonData(DATA.currentMon, MON_DATA_GIGANTAMAX_FACTOR, &gigantamaxFactor); +} + +void TeraType_(u32 sourceLine, u32 teraType) +{ + INVALID_IF(!DATA.currentMon, "TeraType outside of PLAYER/OPPONENT"); + SetMonData(DATA.currentMon, MON_DATA_TERA_TYPE, &teraType); +} + +void Shadow_(u32 sourceLine, bool32 isShadow) +{ + INVALID_IF(!DATA.currentMon, "Shadow outside of PLAYER/OPPONENT"); + SetMonData(DATA.currentMon, MON_DATA_IS_SHADOW, &isShadow); +} + static const char *const sBattlerIdentifiersSingles[] = { "player",