diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 8240a5680191..0a3eff0e43d2 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -23,20 +23,15 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.3 (Latest release) + - 1.10.0 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.4 + - 1.9.3 - 1.9.2 - 1.9.1 - 1.9.0 - - 1.8.6 - - 1.8.5 - - 1.8.4 - - 1.8.3 - - 1.8.2 - - 1.8.1 - - 1.8.0 - - pre-1.8.0 + - pre-1.9.0 validations: required: true - type: input diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 5688f8a7fb9b..4b8eec3a437f 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -23,20 +23,15 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.3 (Latest release) + - 1.10.0 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.4 + - 1.9.3 - 1.9.2 - 1.9.1 - 1.9.0 - - 1.8.6 - - 1.8.5 - - 1.8.4 - - 1.8.3 - - 1.8.2 - - 1.8.1 - - 1.8.0 - - pre-1.8.0 + - pre-1.9.0 validations: required: true - type: input diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index add0633d956f..54335ca5e40a 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -23,20 +23,15 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.3 (Latest release) + - 1.10.0 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.4 + - 1.9.3 - 1.9.2 - 1.9.1 - 1.9.0 - - 1.8.6 - - 1.8.5 - - 1.8.4 - - 1.8.3 - - 1.8.2 - - 1.8.1 - - 1.8.0 - - pre-1.8.0 + - pre-1.9.0 validations: required: true - type: input diff --git a/CHANGELOG.md b/CHANGELOG.md index bb9fec3e7e8c..13d6e4f4ebd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Pokeemerald-Expansion Changelogs +## 1.10.x +- **[Version 1.10.0](docs/changelogs/1.10.x/1.10.0.md) - ✨ Feature Release** + ## 1.9.x +- **[Version 1.9.4](docs/changelogs/1.9.x/1.9.4.md) - 🧹 Bugfix Release** +- **[Version 1.9.3](docs/changelogs/1.9.x/1.9.3.md) - 🧹 Bugfix Release** - **[Version 1.9.2](docs/changelogs/1.9.x/1.9.2.md) - 🧹 Bugfix Release** - **[Version 1.9.1](docs/changelogs/1.9.x/1.9.1.md) - 🧹 Bugfix Release** - **[Version 1.9.0](docs/changelogs/1.9.x/1.9.0.md) - ✨ Feature Release** diff --git a/Makefile b/Makefile index f38b551b0c0b..71d2a48af9a3 100644 --- a/Makefile +++ b/Makefile @@ -438,6 +438,7 @@ libagbsyscall: @$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=1 # Elf from object files +LDFLAGS = -Map ../../$(MAP) $(ELF): $(LD_SCRIPT) $(LD_SCRIPT_DEPS) $(OBJS) libagbsyscall @cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ $(OBJS_REL) $(LIB) | cat @echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ | cat" diff --git a/README.md b/README.md index facd5f562672..277dae2be785 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,16 @@ pokeemerald-expansion is a decomp hack base project based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. It's recommended that any new projects that plan on using it, to clone this repository instead of pret's vanilla repository, as we regurlarly incorporate pret's documentation changes. This is ***NOT*** a standalone romhack, and as such, most features will be unavailable and/or unbalanced if played as is. +## Using pokeemerald-expansion + If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect. You can phrase it as the following: ``` -Based off RHH's pokeemerald-expansion 1.9.3 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.10.0 https://github.com/rh-hideout/pokeemerald-expansion/ ``` +Please follow the instructions in `INSTALL.md` to get pokeemerald-expansion set up on your machine. + ## What features are included? - ***IMPORTANT*❗❗ Read through these to learn what features you can toggle**: - [Battle configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h) @@ -173,7 +177,7 @@ With this, you'll get the latest version of pokeemerald-expansion, plus a couple - Check your current version. - You can check in the debug menu's `Utilities -> Expansion Version` option. - If the option is not available, you possibly have version 1.6.2 or older. In that case, please check the [changelogs](CHANGELOG.md) to determine your version based on the features available on your repository. -- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.9.3, use `git pull RHH expansion/1.9.3`). +- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.10.0, use `git pull RHH expansion/1.10.0`). - ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on) - Alternatively, you can update to unreleased versions of the expansion. - ***master (stable):*** It contains unreleased **bugfixes** that will come in the next patch version. To merge, use `git pull RHH master`. diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index c34d90507412..0b55b5a57430 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -798,9 +798,7 @@ 2: .endm - .macro setmultihitcounter value:req - .byte 0x8d - .byte \value + .macro unused_0x8d .endm .macro initmultihitstring diff --git a/charmap.txt b/charmap.txt index e8e43dc99650..63c2f6ebe10c 100644 --- a/charmap.txt +++ b/charmap.txt @@ -370,7 +370,7 @@ B_ATK_NAME_WITH_PREFIX = FD 0F B_DEF_NAME_WITH_PREFIX = FD 10 B_EFF_NAME_WITH_PREFIX = FD 11 @ EFF = short for gEffectBattler @ FD 12 - preiously gActiveBattler with prefix -B_SCR_ACTIVE_NAME_WITH_PREFIX = FD 13 +B_SCR_NAME_WITH_PREFIX = FD 13 B_CURRENT_MOVE = FD 14 B_LAST_MOVE = FD 15 B_LAST_ITEM = FD 16 @@ -416,7 +416,7 @@ B_DEF_TEAM2 = FD 3B B_ATK_NAME_WITH_PREFIX2 = FD 3E B_DEF_NAME_WITH_PREFIX2 = FD 3F B_EFF_NAME_WITH_PREFIX2 = FD 40 -B_SCR_ACTIVE_NAME_WITH_PREFIX2 = FD 41 +B_SCR_NAME_WITH_PREFIX2 = FD 41 B_TRAINER1_NAME_WITH_CLASS = FD 42 B_TRAINER2_NAME_WITH_CLASS = FD 43 B_PARTNER_NAME_WITH_CLASS = FD 44 diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 643ee2cd0efa..80d50710baa7 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -3666,7 +3666,7 @@ gBattleAnimMove_DarkVoid:: loopsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_ATTACKER, 5, 2 delay 48 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, -768, 21, 0, 112 @Last is duration - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, -768, 21, 0, 112 @Last is duration + createsprite gSlideMonToOffsetPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, -768, 21, 0, 112 @Last is duration delay 64 invisible ANIM_TARGET invisible ANIM_DEF_PARTNER @@ -3674,7 +3674,7 @@ gBattleAnimMove_DarkVoid:: createsprite gDarkVoidPurpleStarsTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_DEF_PARTNER, 0, 32, 60 waitforvisualfinish createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, 16 - createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0, 16 + createsprite gSlideMonToOriginalPosPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0, 16 delay 32 call UnsetPsychicBg visible ANIM_TARGET @@ -10093,7 +10093,6 @@ gBattleAnimMove_FloralHealing:: loadspritegfx ANIM_TAG_ORBS @circles loadspritegfx ANIM_TAG_PINK_PETAL @pink particles monbg ANIM_ATTACKER - monbg ANIM_TARGET playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER call CIRCLES_LEAVES call CIRCLES_LEAVES @@ -10101,6 +10100,7 @@ gBattleAnimMove_FloralHealing:: panse SE_M_COMET_PUNCH, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0 playsewithpan SE_M_TWISTER, 0x0 createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x46, 0x1, 0x40 + clearmonbg ANIM_ATTACKER delay 0x2 createsprite gFloralHealingWindLeavesTemplate, ANIM_ATTACKER, 2, 0x3c, 0x0, 0x40 delay 0x2 @@ -10123,6 +10123,7 @@ gBattleAnimMove_FloralHealing:: createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x55, 0x0, 0x78 delay 0x2 loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 0x12, 0xa + monbg ANIM_TARGET call FloralHealingSpores call FloralHealingSpores call FloralHealingSpores @@ -10133,7 +10134,6 @@ gBattleAnimMove_FloralHealing:: createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 16, 0xc, 0xfffb, 0x1, 0x0, 0x20, 0x3c, 0x1 waitforvisualfinish clearmonbg ANIM_TARGET - clearmonbg ANIM_ATTACKER end FloralHealingSpores: createsprite gFloralHealingFlowerTemplate, ANIM_ATTACKER, 2, 0x0, 0xffec, 0x55, 0x50, 0x0 @@ -33527,7 +33527,7 @@ gBattleAnimMove_ClangorousSoulblaze:: delay 0x2 createvisualtask AnimTask_StartSlidingBg, 0x5, 0x0, 0xFFE0, 0x1, 0xffff createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0xfd00, 0xa, 0x0, 0x2a - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0xfd00, 0xa, 0x0, 0x2a + createsprite gSlideMonToOffsetPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0xfd00, 0xa, 0x0, 0x2a delay 0x20 createvisualtask AnimTask_StartSlidingBg, 0x5, 0x0, 0x20, 0x1, 0xffff delay 0xC @@ -33719,7 +33719,7 @@ FINISH_SOULBLAZE: call ResetFromWhiteScreen blendoff createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0x0, 0x10 - createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0x0, 0x10 + createsprite gSlideMonToOriginalPosPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0x0, 0x10 waitforvisualfinish end ClangorousSoulblazeEnergySwirl: @@ -34742,7 +34742,7 @@ gBattleAnimMove_GMaxTerror:: gBattleAnimMove_MaxPhantasm:: createvisualtask AnimTask_DynamaxGrowth, 0x5, 0x1, 0x1 waitforvisualfinish - goto gBattleAnimMove_PhantomForce + goto gBattleAnimMove_ShadowBall end gBattleAnimMove_GMaxGravitas:: diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 9b245d51f8de..68476cff2cff 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2401,7 +2401,6 @@ BattleScript_EffectHealingWish:: storehealingwish BS_ATTACKER .if B_HEALING_WISH_SWITCH <= GEN_4 openpartyscreen BS_ATTACKER, BattleScript_EffectHealingWishEnd - switchoutabilities BS_ATTACKER waitstate switchhandleorder BS_ATTACKER, 2 returnatktoball @@ -3013,30 +3012,17 @@ BattleScript_CantMakeAsleep:: orhalfword gMoveResultFlags, MOVE_RESULT_FAILED goto BattleScript_MoveEnd -BattleScript_EffectAbsorb:: - call BattleScript_EffectHit_Ret - jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_AbsorbHealBlock - setdrainedhp - manipulatedamage DMG_BIG_ROOT - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE - jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_AbsorbLiquidOoze - setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB - goto BattleScript_AbsorbUpdateHp -BattleScript_AbsorbLiquidOoze:: +BattleScript_EffectAbsorbLiquidOoze:: call BattleScript_AbilityPopUpTarget - manipulatedamage DMG_CHANGE_SIGN - setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB_OOZE -BattleScript_AbsorbUpdateHp:: + goto BattleScript_EffectAbsorb + +BattleScript_EffectAbsorb:: healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER - jumpifmovehadnoeffect BattleScript_AbsorbTryFainting printfromtable gAbsorbDrainStringIds waitmessage B_WAIT_TIME_LONG -BattleScript_AbsorbTryFainting:: tryfaintmon BS_ATTACKER -BattleScript_AbsorbHealBlock:: - tryfaintmon BS_TARGET - goto BattleScript_MoveEnd + return BattleScript_EffectExplosion:: attackcanceler @@ -4161,6 +4147,7 @@ BattleScript_EffectMinimize:: BattleScript_EffectCurse:: jumpiftype BS_ATTACKER, TYPE_GHOST, BattleScript_GhostCurse attackcanceler + jumpiftype BS_ATTACKER, TYPE_GHOST, BattleScript_DoGhostCurse attackstring ppreduce jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_SPEED, MIN_STAT_STAGE, BattleScript_CurseTrySpeed @@ -5769,7 +5756,6 @@ BattleScript_PrintFullBox:: BattleScript_ActionSwitch:: hpthresholds2 BS_ATTACKER - saveattacker printstring STRINGID_RETURNMON jumpifbattletype BATTLE_TYPE_DOUBLE, BattleScript_PursuitSwitchDmgSetMultihit setmultihit 1 @@ -5787,7 +5773,6 @@ BattleScript_DoSwitchOut:: switchoutabilities BS_ATTACKER updatedynamax waitstate - restoreattacker returnatktoball waitstate drawpartystatussummary BS_ATTACKER @@ -6046,33 +6031,34 @@ BattleScript_SafeguardEnds:: waitmessage B_WAIT_TIME_LONG end2 -BattleScript_LeechSeedTurnDrain:: - playanimation BS_ATTACKER, B_ANIM_LEECH_SEED_DRAIN, sB_ANIM_ARG1 - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE - healthbarupdate BS_ATTACKER - datahpupdate BS_ATTACKER - copyword gBattleMoveDamage, gHpDealt - jumpifability BS_ATTACKER, ABILITY_LIQUID_OOZE, BattleScript_LeechSeedTurnPrintLiquidOoze - setbyte cMULTISTRING_CHOOSER, B_MSG_LEECH_SEED_DRAIN - jumpifstatus3 BS_TARGET, STATUS3_HEAL_BLOCK, BattleScript_LeechSeedHealBlock - manipulatedamage DMG_BIG_ROOT - goto BattleScript_LeechSeedTurnPrintAndUpdateHp -BattleScript_LeechSeedTurnPrintLiquidOoze:: +BattleScript_LeechSeedTurnDrainLiquidOoze:: + call BattleScript_LeechSeedTurnDrain + manipulatedamage DMG_CHANGE_SIGN copybyte gBattlerAbility, gBattlerAttacker call BattleScript_AbilityPopUp - setbyte cMULTISTRING_CHOOSER, B_MSG_LEECH_SEED_OOZE -BattleScript_LeechSeedTurnPrintAndUpdateHp:: - orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE + goto BattleScript_LeechSeedTurnDrainGainHp + +BattleScript_LeechSeedTurnDrainHealBlock:: + call BattleScript_LeechSeedTurnDrain + end2 + +BattleScript_LeechSeedTurnDrainRecovery:: + call BattleScript_LeechSeedTurnDrain +BattleScript_LeechSeedTurnDrainGainHp: + manipulatedamage DMG_BIG_ROOT healthbarupdate BS_TARGET datahpupdate BS_TARGET printfromtable gLeechSeedStringIds waitmessage B_WAIT_TIME_LONG - tryfaintmon BS_ATTACKER tryfaintmon BS_TARGET end2 -BattleScript_LeechSeedHealBlock: - setword gBattleMoveDamage, 0 - goto BattleScript_LeechSeedTurnPrintAndUpdateHp + +BattleScript_LeechSeedTurnDrain: + playanimation BS_ATTACKER, B_ANIM_LEECH_SEED_DRAIN, sB_ANIM_ARG1 + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + tryfaintmon BS_ATTACKER + return BattleScript_BideStoringEnergy:: printstring STRINGID_PKMNSTORINGENERGY @@ -6990,26 +6976,17 @@ BattleScript_WishMegaEvolution:: goto BattleScript_MegaEvolutionAfterString BattleScript_PrimalReversion:: - call BattleScript_PrimalReversionRet - end3 - -BattleScript_PrimalReversionRestoreAttacker:: - call BattleScript_PrimalReversionRet - copybyte gBattlerAttacker, sSAVED_BATTLER - end3 - -BattleScript_PrimalReversionRet:: flushtextbox setbyte gIsCriticalHit, 0 - handleprimalreversion BS_ATTACKER, 0 - handleprimalreversion BS_ATTACKER, 1 - playanimation BS_ATTACKER, B_ANIM_PRIMAL_REVERSION + handleprimalreversion BS_SCRIPTING, 0 + handleprimalreversion BS_SCRIPTING, 1 + playanimation BS_SCRIPTING, B_ANIM_PRIMAL_REVERSION waitanimation - handleprimalreversion BS_ATTACKER, 2 + handleprimalreversion BS_SCRIPTING, 2 printstring STRINGID_PKMNREVERTEDTOPRIMAL waitmessage B_WAIT_TIME_LONG - switchinabilities BS_ATTACKER - return + switchinabilities BS_SCRIPTING + end3 BattleScript_UltraBurst:: flushtextbox @@ -9655,7 +9632,9 @@ BattleScript_EjectButtonActivates:: removeitem BS_SCRIPTING makeinvisible BS_SCRIPTING openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd + copybyte sSAVED_BATTLER, sBATTLER switchoutabilities BS_SCRIPTING + copybyte sBATTLER, sSAVED_BATTLER waitstate switchhandleorder BS_SCRIPTING 0x2 returntoball BS_SCRIPTING, FALSE @@ -9752,6 +9731,7 @@ BattleScript_PastelVeilEnd: end3 BattleScript_NeutralizingGasExits:: + saveattacker savetarget pause B_WAIT_TIME_SHORT printstring STRINGID_NEUTRALIZINGGASOVER @@ -9761,6 +9741,7 @@ BattleScript_NeutralizingGasExitsLoop: switchinabilities BS_TARGET addbyte gBattlerTarget, 1 jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop + restoreattacker restoretarget return diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index ac4698fdc32f..cb02bb306e77 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -18,7 +18,10 @@ - [v1.6.x](tutorials/how_to_new_pokemon_1_6_0.md) - [How to use the Testing System](tutorials/how_to_testing_system.md) - [Changelog](./CHANGELOG.md) + - [1.10.x]() + - [Version 1.10.0](changelogs/1.9.x/1.9.4.md) - [1.9.x]() + - [Version 1.9.4](changelogs/1.9.x/1.9.4.md) - [Version 1.9.3](changelogs/1.9.x/1.9.3.md) - [Version 1.9.2](changelogs/1.9.x/1.9.2.md) - [Version 1.9.1](changelogs/1.9.x/1.9.1.md) diff --git a/docs/changelogs/1.10.0/1.10.0.md b/docs/changelogs/1.10.0/1.10.0.md new file mode 100644 index 000000000000..9cf2f9b41e99 --- /dev/null +++ b/docs/changelogs/1.10.0/1.10.0.md @@ -0,0 +1,324 @@ +# Version 1.10.0 + +```md +## How to update +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.10.0`. +``` + +## 🌋 *REFACTORS* 🌋 +📜 = Uses a migration script. +* Changes Evolution methods to Enums by @AlexOn1ine in [#4977](https://github.com/rh-hideout/pokeemerald-expansion/pull/4977) +* Turn item hold effects into an enum by @Bassoonian in [#5498](https://github.com/rh-hideout/pokeemerald-expansion/pull/5498) +* Change `GET_MOVE_TYPE` to a function by @AlexOn1ine in [#5090](https://github.com/rh-hideout/pokeemerald-expansion/pull/5090) +* Created `COMPOUND_STRING`s for default player names by @fdeblasio in [#5037](https://github.com/rh-hideout/pokeemerald-expansion/pull/5037) +* Removed agbcc by @mrgriffin in [#4994](https://github.com/rh-hideout/pokeemerald-expansion/pull/4994) +* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027) +* Removed all instances of `gBitTable[x]` by @hedara90 in [#5123](https://github.com/rh-hideout/pokeemerald-expansion/pull/5123) +* Made `BuildColorMaps` redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289) +* Removed `FRONTIER_BRAIN_SPRITES` and updated `TRAINER_SPRITE`, `TRAINER_BACK_SPRITE`, and `TRAINER_CLASS` by @fdeblasio in [#5166](https://github.com/rh-hideout/pokeemerald-expansion/pull/5166) +* Added `ShouldSwitch` result to `AiLogicData` by @Pawkkie and @AlexOn1ine had the idea! in [#5440](https://github.com/rh-hideout/pokeemerald-expansion/pull/5440) +* Switch AI refactor + considers free switches by @Pawkkie in [#5379](https://github.com/rh-hideout/pokeemerald-expansion/pull/5379) +* Refactor `ShouldSwitchIfAllBadMoves` by @Pawkkie in [#5452](https://github.com/rh-hideout/pokeemerald-expansion/pull/5452) +* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549) + - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it. + - Also: + - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP` + - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP` +* Update battle messages to Gen 5+ standards by @kittenchilly in [#3240](https://github.com/rh-hideout/pokeemerald-expansion/pull/3240) +* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466) +* Unwind `TRAINER_CLASS` macro by @SBird1337 in [#5611](https://github.com/rh-hideout/pokeemerald-expansion/pull/5611) +* Refactors Absorb to use `Moveend` by @AlexOn1ine in [#5670](https://github.com/rh-hideout/pokeemerald-expansion/pull/5670) + * For new absorbing moves an argument should be added in `moves_info.h` +* Changes name of `B_SCR_NAME_WITH_PREFIX` by @AlexOn1ine in [#5675](https://github.com/rh-hideout/pokeemerald-expansion/pull/5675) + +## 🧬 General 🧬 +### Added +* Added performance counter by @hedara90 and @SBird1337 provided the actual code in [#5284](https://github.com/rh-hideout/pokeemerald-expansion/pull/5284) +* Added debug build target by @u8-Salem in [#4817](https://github.com/rh-hideout/pokeemerald-expansion/pull/4817) +* Added `AUTO_SCROLL_TEXT` and `NUM_FRAMES_AUTO_SCROLL_DELAY` by @pkmnsnfrn in [#5054](https://github.com/rh-hideout/pokeemerald-expansion/pull/5054) +* Adds `SAVE_TYPE_ERROR_SCREEN` by @pkmnsnfrn in [#5188](https://github.com/rh-hideout/pokeemerald-expansion/pull/5188) +* Move Relearner and Renaming From Summary Screen by @ravepossum in [#5513](https://github.com/rh-hideout/pokeemerald-expansion/pull/5513) +* Automatic Line Breaks, somewhat even lines by @hedara90 and @AsparagusEduardo in [#5689](https://github.com/rh-hideout/pokeemerald-expansion/pull/5689) + - Automatically insert line breaks into a string with `BreakStringAutomatic`. + - This function does not modify strings with existing line breaks. + - Remove existing line breaks from a string with `StripLineBreaks`. + +### Changed +* Removed agbcc by @mrgriffin in [#4994](https://github.com/rh-hideout/pokeemerald-expansion/pull/4994) +* Removed all instances of `gBitTable[x]` by @hedara90 in [#5123](https://github.com/rh-hideout/pokeemerald-expansion/pull/5123) +* Converted Mechadoll text to `COMPOUND_STRING`s by @fdeblasio in [#5276](https://github.com/rh-hideout/pokeemerald-expansion/pull/5276) +* New terrain bgs by @TheTrueSadfish in [#5162](https://github.com/rh-hideout/pokeemerald-expansion/pull/5162) +* Removed agbcc screenshots from `.gitignore` by @Bassoonian in [#5538](https://github.com/rh-hideout/pokeemerald-expansion/pull/5538) +* Set default battle shadow to Gen3 by @hedara90 in [#5632](https://github.com/rh-hideout/pokeemerald-expansion/pull/5632) + - Note: Trainerslides don't work properly with Gen4 shadows. +* Convert 3 variouses to `callnatives` by @AlexOn1ine in [#5646](https://github.com/rh-hideout/pokeemerald-expansion/pull/5646) + +## 🗺️ Overworld 🗺️ +### Added +* FRLG+ whiteout message by @cawtds in [#4967](https://github.com/rh-hideout/pokeemerald-expansion/pull/4967) +* Dynamic Move Types in Summary Screen/Battle by @Galaxeeh in [#5084](https://github.com/rh-hideout/pokeemerald-expansion/pull/5084) +* Adds `OW_BERRY_IMMORTAL` by @pkmnsnfrn in [#5187](https://github.com/rh-hideout/pokeemerald-expansion/pull/5187) +* (Default Off) Item Description Headers by @ghoulslash in [#4767](https://github.com/rh-hideout/pokeemerald-expansion/pull/4767) +* RTC-based wild encounters by @hjk321 in [#5313](https://github.com/rh-hideout/pokeemerald-expansion/pull/5313) +* Added `MB_X_Y_STAIR_WARP` metatile behaviors by @pkmnsnfrn in [#5278](https://github.com/rh-hideout/pokeemerald-expansion/pull/5278) +* Added Sideways Stairs by @ghoulslash in [#4836](https://github.com/rh-hideout/pokeemerald-expansion/pull/4836) +* Added `OW_UNION_DISABLE_CHECK` and `OW_FLAG_MOVE_UNION_ROOM_CHECK` by @pkmnsnfrn in [#5448](https://github.com/rh-hideout/pokeemerald-expansion/pull/5448) +* Adds new scripting macros to increase developer quality of life by @pkmnsnfrn in [#5177](https://github.com/rh-hideout/pokeemerald-expansion/pull/5177) +* Added more later gen fishing mechanics by @kittenchilly in [#5518](https://github.com/rh-hideout/pokeemerald-expansion/pull/5518) + +### Changed +* Created PokeNav `COMPOUND_STRING`s by @fdeblasio in [#4983](https://github.com/rh-hideout/pokeemerald-expansion/pull/4983) +* Added `I_REPEL_INCLUDE_FAINTED` config and behavior by @kittenchilly in [#5239](https://github.com/rh-hideout/pokeemerald-expansion/pull/5239) +* RTC-based wild encounters follow up by @AlexOn1ine in [#5328](https://github.com/rh-hideout/pokeemerald-expansion/pull/5328) +* Revert rtc based encounters by @AlexOn1ine in [#5331](https://github.com/rh-hideout/pokeemerald-expansion/pull/5331) +* Made BuildColorMaps redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289) +* Added `OW_AUTO_SIGNPOST` and associated metatile behaviors by @pkmnsnfrn in [#5044](https://github.com/rh-hideout/pokeemerald-expansion/pull/5044) +* Added support for overworld sprite gender differences + add all the sprites by @kittenchilly in [#5394](https://github.com/rh-hideout/pokeemerald-expansion/pull/5394) + +### Fixed +* Added some null pointer checks by @tertu-m in [#5130](https://github.com/rh-hideout/pokeemerald-expansion/pull/5130) +* Reset item flags on new game by @ghoulslash in [#5363](https://github.com/rh-hideout/pokeemerald-expansion/pull/5363) +* Follower female fix by @hedara90 in [#5475](https://github.com/rh-hideout/pokeemerald-expansion/pull/5475) + +## 🐉 Pokémon 🐉 +### Added +* Added config to change Vivillon's breeding form by @kittenchilly in [#4813](https://github.com/rh-hideout/pokeemerald-expansion/pull/4813) +* Added back GBA sprites via config by @AsparagusEduardo and @AlexOn1ine for their help with script to migrate data from vanilla to our current `gSpeciesInfo` in [#5206](https://github.com/rh-hideout/pokeemerald-expansion/pull/5206) +* Added config to disable gender differences by @AsparagusEduardo in [#5595](https://github.com/rh-hideout/pokeemerald-expansion/pull/5595) + +### Changed +* Made perfect IV count into a granular setting by @AsparagusEduardo in [#5115](https://github.com/rh-hideout/pokeemerald-expansion/pull/5115) +* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075) +* Added support for overworld sprite gender differences + add all the sprites by @kittenchilly in [#5394](https://github.com/rh-hideout/pokeemerald-expansion/pull/5394) +* Renamed folders and symbols to match species defines by @AsparagusEduardo in [#5581](https://github.com/rh-hideout/pokeemerald-expansion/pull/5581) + - Burmy and Wormadam footprints were in a `plant` subfolder. They have been moved to the species root folder + - Paldean Wooper's subfolder was named `wooper_paldean` instead of just `paldean`. This has been corrected. + - Zen Mode Galarian Darmanitan's folder was located in `darmanitan/galarian/zen_mode`. This has been corrected to `darmanitan/galar_zen`, alongside Galarian Standard Mode's `darmanitan/galar_standard`. + - Also updated Ogerpon's folders similarly. + - Renamed `SPECIES_PIKACHU_PARTNER_CAP` to `SPECIES_PIKACHU_PARTNER`. +* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547) + - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1. + +### Fixed +* Follower female fix by @hedara90 in [#5475](https://github.com/rh-hideout/pokeemerald-expansion/pull/5475) +* Fixed some gba sprites by @SubzeroEclipse in [#5607](https://github.com/rh-hideout/pokeemerald-expansion/pull/5607) + +## ⚔️ Battle General ⚔️ +### Added +* FRLG+ whiteout message by @cawtds in [#4967](https://github.com/rh-hideout/pokeemerald-expansion/pull/4967) +* Added B_SHOW_TYPES and cleaned up IsDoubleBattle by @pkmnsnfrn in [#5131](https://github.com/rh-hideout/pokeemerald-expansion/pull/5131) +* EV Caps and EV Items by @Flash1Lucky and @AlexOn1ine in [#5269](https://github.com/rh-hideout/pokeemerald-expansion/pull/5269) +* Added in-battle shadows underneath all enemy battlers by @lhearachel in [#5178](https://github.com/rh-hideout/pokeemerald-expansion/pull/5178) +* Added Gen 1 Crit Chance by @Pawkkie in [#5439](https://github.com/rh-hideout/pokeemerald-expansion/pull/5439) +* Added battle flag that prevents running from wild Pokémon by @SarnPoke in [#5502](https://github.com/rh-hideout/pokeemerald-expansion/pull/5502) + +### Changed +* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027) +* Removed some hardcoding of move IDs + Gen4/5 Defog by @AsparagusEduardo in [#5156](https://github.com/rh-hideout/pokeemerald-expansion/pull/5156) +* Convert 8 various to `callnatives` by @AsparagusEduardo in [#5172](https://github.com/rh-hideout/pokeemerald-expansion/pull/5172) +* Anger Shell use `saveattacker` by @ghoulslash in [#5409](https://github.com/rh-hideout/pokeemerald-expansion/pull/5409) +* Clean up Unseen Fist Check by @AlexOn1ine in [#5420](https://github.com/rh-hideout/pokeemerald-expansion/pull/5420) +* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075) +* Removes Crit Chance preproc by @AlexOn1ine in [#5520](https://github.com/rh-hideout/pokeemerald-expansion/pull/5520) +* Update battle messages to Gen 5+ standards by @kittenchilly in [#3240](https://github.com/rh-hideout/pokeemerald-expansion/pull/3240) +* More post-#3240 cleanup by @kittenchilly in [#5593](https://github.com/rh-hideout/pokeemerald-expansion/pull/5593) +* Unwind `TRAINER_CLASS` macro by @SBird1337 in [#5611](https://github.com/rh-hideout/pokeemerald-expansion/pull/5611) +* Removes redundant Decorate check by @AlexOn1ine in [#5696](https://github.com/rh-hideout/pokeemerald-expansion/pull/5696) +* Changes target bit of Flower Shield by @AlexOn1ine in [#5698](https://github.com/rh-hideout/pokeemerald-expansion/pull/5698) + +### Fixed +* Fixed a sprite issue with `B_SHOW_TYPES` by @pkmnsnfrn in [#5157](https://github.com/rh-hideout/pokeemerald-expansion/pull/5157) +* Dynamic Move Display fixes by @Galaxeeh in [#5251](https://github.com/rh-hideout/pokeemerald-expansion/pull/5251) +* Fixed a display issue with `B_SHOW_TYPES` by @pkmnsnfrn and @iriv24 in [#5201](https://github.com/rh-hideout/pokeemerald-expansion/pull/5201) +* Fixed Gen 3 foreseen and Beat Up damage type by @hedara90 in [#5323](https://github.com/rh-hideout/pokeemerald-expansion/pull/5323) +* Fixes Defog used by the wrong side when there is a Substitue and Screen by @AlexOn1ine in [#5381](https://github.com/rh-hideout/pokeemerald-expansion/pull/5381) +* Fixes Hidden Power dynamic type bug by @AlexOn1ine in [#5463](https://github.com/rh-hideout/pokeemerald-expansion/pull/5463) +* Display the correct shadow size when sending out a new Pokemon by @lhearachel in [#5618](https://github.com/rh-hideout/pokeemerald-expansion/pull/5618) +* Fixed text wrap obtaining the incorrect glyph width by @AsparagusEduardo and @AlexOn1ine for their help verifying that the fix works with one of his custom strings in [#5620](https://github.com/rh-hideout/pokeemerald-expansion/pull/5620) +* Improve line breaks/scrolls by @cawtds in [#5641](https://github.com/rh-hideout/pokeemerald-expansion/pull/5641) +* Fixed Order Up + Tera Stellar breaking each other with Commander by @PhallenTree in [#5667](https://github.com/rh-hideout/pokeemerald-expansion/pull/5667) +* Fixes wrong Id when AI chooses mon to switch in by @AlexOn1ine in [#5684](https://github.com/rh-hideout/pokeemerald-expansion/pull/5684) +* Fixes Absorb regression caused by #5670 by @AlexOn1ine in [#5688](https://github.com/rh-hideout/pokeemerald-expansion/pull/5688) +* Fixes heal blocked leeach seed in tests by @AlexOn1ine in [#5700](https://github.com/rh-hideout/pokeemerald-expansion/pull/5700) +* Trainer class+name expansion fix for Battle Frontier by @hedara90 in [#5699](https://github.com/rh-hideout/pokeemerald-expansion/pull/5699) + +## 🤹 Moves 🤹 +### Changed +* Added Population Bomb animation by @kittenchilly in [#5194](https://github.com/rh-hideout/pokeemerald-expansion/pull/5194) +* Move battle anim arrays to C by @cawtds in [#5306](https://github.com/rh-hideout/pokeemerald-expansion/pull/5306) +* Grass/Water Pledge Swamp Animation + Sea of Fire animation tweak by @SonikkuA-DatH in [#5325](https://github.com/rh-hideout/pokeemerald-expansion/pull/5325) +* New animations for many moves more details in description by @TheTrueSadfish in [#5367](https://github.com/rh-hideout/pokeemerald-expansion/pull/5367) +* Use move effect for some moves instead of ids by @AlexOn1ine in [#5433](https://github.com/rh-hideout/pokeemerald-expansion/pull/5433) +* Adds Commander and Order Up by @AlexOn1ine in [#5246](https://github.com/rh-hideout/pokeemerald-expansion/pull/5246) +* Heart Swap Move Animation by @SonikkuA-DatH in [#5460](https://github.com/rh-hideout/pokeemerald-expansion/pull/5460) +* Update `shed_tail.c` by @Bassoonian in [#5494](https://github.com/rh-hideout/pokeemerald-expansion/pull/5494) +* Added Ion Deluge animation by @kittenchilly in [#5467](https://github.com/rh-hideout/pokeemerald-expansion/pull/5467) +* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549) + - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it. Also: + - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP` + - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP` +* Refactors Absorb to use Moveend by @AlexOn1ine in [#5670](https://github.com/rh-hideout/pokeemerald-expansion/pull/5670) + * For new absorbing moves an argument should be added in `moves_info.h` + +### Fixed +* Dark Void, Clangorous Soulblaze, vortex animation fixes by @TheTrueSadfish in [#5650](https://github.com/rh-hideout/pokeemerald-expansion/pull/5650) + +## 🎭 Abilities 🎭 +### Changed +* Adds Commander and Order Up by @AlexOn1ine in [#5246](https://github.com/rh-hideout/pokeemerald-expansion/pull/5246) + +## 🧶 Items 🧶 +### Added +* Adds `OW_BERRY_IMMORTAL` by @pkmnsnfrn in [#5187](https://github.com/rh-hideout/pokeemerald-expansion/pull/5187) +* Added functionality to Poké Flute and Town Map by @kittenchilly and @LOuroboros basically did the Town Map implementation in [#5405](https://github.com/rh-hideout/pokeemerald-expansion/pull/5405) +* Decouple Poke Ball ids from item ids by @AlexOn1ine in [#5560](https://github.com/rh-hideout/pokeemerald-expansion/pull/5560) + +### Changed +* Consolidated the values of Rotom's moves and added Gen9 base form effect by @fdeblasio in [#5186](https://github.com/rh-hideout/pokeemerald-expansion/pull/5186) +* Added `I_REPEL_INCLUDE_FAINTED` config and behavior by @kittenchilly in [#5239](https://github.com/rh-hideout/pokeemerald-expansion/pull/5239) + +### Fixed +* Replace hardcoded flute check with consumability check by @Bassoonian in [#5508](https://github.com/rh-hideout/pokeemerald-expansion/pull/5508) + +## 🤖 Battle AI 🤖 +### Added +* Adds config to show target of ingame partner by @AlexOn1ine in [#5307](https://github.com/rh-hideout/pokeemerald-expansion/pull/5307) +* Switch AI refactor + considers free switches by @Pawkkie in [#5379](https://github.com/rh-hideout/pokeemerald-expansion/pull/5379) +* New AI flag for marking the two last Pokémon as Ace Pokémon by @GhoulMage in [#5587](https://github.com/rh-hideout/pokeemerald-expansion/pull/5587) + +### Changed +* Chilly Reception AI by @kittenchilly in [#5271](https://github.com/rh-hideout/pokeemerald-expansion/pull/5271) +* Shed Tail AI by @SarnPoke and @AlexOn1ine, @Pawkkie in [#5275](https://github.com/rh-hideout/pokeemerald-expansion/pull/5275) +* More missing AI logic by @kittenchilly in [#5279](https://github.com/rh-hideout/pokeemerald-expansion/pull/5279) +* Adds basic trainer and smart trainer flags by @AlexOn1ine in [#5298](https://github.com/rh-hideout/pokeemerald-expansion/pull/5298) +* `AI_FLAG_SETUP_FIRST_TURN` rename and clarifications by @Pawkkie in [#5310](https://github.com/rh-hideout/pokeemerald-expansion/pull/5310) +* Added Composite AI Flags to Docs by @Pawkkie in [#5349](https://github.com/rh-hideout/pokeemerald-expansion/pull/5349) +* AI frostbite score fixes and improvements by @Pawkkie and @kittenchilly for the suggestion! in [#5362](https://github.com/rh-hideout/pokeemerald-expansion/pull/5362) +* Switch AI `hitsToKO` considers one shot prevention by @Pawkkie in [#5371](https://github.com/rh-hideout/pokeemerald-expansion/pull/5371) +* Adds `CanEndureHit` AI function by @AlexOn1ine in [#5373](https://github.com/rh-hideout/pokeemerald-expansion/pull/5373) +* Switch AI `hitsToKO` considers Disguise by @Pawkkie in [#5375](https://github.com/rh-hideout/pokeemerald-expansion/pull/5375) +* Added `ShouldSwitch` result to `AiLogicData` by @Pawkkie and @AlexOn1ine had the idea! in [#5440](https://github.com/rh-hideout/pokeemerald-expansion/pull/5440) +* Removes duplicate code in AI functions by @AlexOn1ine in [#5457](https://github.com/rh-hideout/pokeemerald-expansion/pull/5457) +* Unify `GetBattlerAbility`/`TerrainAffected` to remove duplicate ai function by @AlexOn1ine in [#5497](https://github.com/rh-hideout/pokeemerald-expansion/pull/5497) +* `ShouldSwitchIfGameStatePrompt` Tests by @Pawkkie in [#5462](https://github.com/rh-hideout/pokeemerald-expansion/pull/5462) +* `AI_FLAG_ACE_POKEMON` takes into account separate trainers by @GhoulMage and @/uvula on Discord noted the weird behaviour. in [#5608](https://github.com/rh-hideout/pokeemerald-expansion/pull/5608) + - Fix for the AI not considering both trainers Ace Pokémons in double battles with `AI_FLAG_ACE_POKEMON`. +* Moves that deal a Fixed amount don't need AI handling by @AlexOn1ine in [#5614](https://github.com/rh-hideout/pokeemerald-expansion/pull/5614) +* Combines `CalculateMoveDamage` arguments into a struct by @AlexOn1ine in [#5570](https://github.com/rh-hideout/pokeemerald-expansion/pull/5570) + +### Fixed +* AI burn score fixes and improvements by @Pawkkie and @iriv24 and @AlexOn1ine in [#5356](https://github.com/rh-hideout/pokeemerald-expansion/pull/5356) +* Improve AI's Skill Swap handling in double battles by @Pawkkie in [#5360](https://github.com/rh-hideout/pokeemerald-expansion/pull/5360) +* Refactor `ShouldSwitchIfAllBadMoves` by @Pawkkie in [#5452](https://github.com/rh-hideout/pokeemerald-expansion/pull/5452) +* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466) +* Fixes Switch in flag not restoring mons properly with test by @Pawkkie and @iriv24 for finding, @AlexOn1ine for fixing in [#5746](https://github.com/rh-hideout/pokeemerald-expansion/pull/5746) + +## 🧹 Other Cleanup 🧹 +* Removed metadata in AIF files by @SombrAbsol in [#4958](https://github.com/rh-hideout/pokeemerald-expansion/pull/4958) +* Removed `gPaletteDecompressionBuffer` and unused palette functions/vars by @DizzyEggg in [#4841](https://github.com/rh-hideout/pokeemerald-expansion/pull/4841) +* Changes Evolution methods to `enum`s by @AlexOn1ine in [#4977](https://github.com/rh-hideout/pokeemerald-expansion/pull/4977) +* Doesn't compile on some compilers by @AlexOn1ine in [#5099](https://github.com/rh-hideout/pokeemerald-expansion/pull/5099) +* Update `event.inc` to accomodate new `gDecompressionBuffer` name by @Bassoonian in [#5100](https://github.com/rh-hideout/pokeemerald-expansion/pull/5100) +* Created `COMPOUND_STRING`s for default player names by @fdeblasio in [#5037](https://github.com/rh-hideout/pokeemerald-expansion/pull/5037) +* Changed single-use berry blender strings to be `COMPOUND_STRING`s by @fdeblasio in [#4963](https://github.com/rh-hideout/pokeemerald-expansion/pull/4963) +* Made perfect IV count into a granular setting by @AsparagusEduardo in [#5115](https://github.com/rh-hideout/pokeemerald-expansion/pull/5115) +* Dynamic move type clean up by @AlexOn1ine in [#5132](https://github.com/rh-hideout/pokeemerald-expansion/pull/5132) +* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027) +* Removed some hardcoding of move IDs + Gen4/5 Defog by @AsparagusEduardo in [#5156](https://github.com/rh-hideout/pokeemerald-expansion/pull/5156) +* Teatime animations use `B_WAIT_TIME_LONG` by @AsparagusEduardo in [#5173](https://github.com/rh-hideout/pokeemerald-expansion/pull/5173) +* Created PokeNav `COMPOUND_STRING`s by @fdeblasio in [#4983](https://github.com/rh-hideout/pokeemerald-expansion/pull/4983) +* Removed `gBitTable` usage again by @hedara90 in [#5193](https://github.com/rh-hideout/pokeemerald-expansion/pull/5193) +* Removed support for the original LCG random number generator by @tertu-m in [#5078](https://github.com/rh-hideout/pokeemerald-expansion/pull/5078) +* Deprecate MMBN Names by @pkmnsnfrn in [#5240](https://github.com/rh-hideout/pokeemerald-expansion/pull/5240) +* Convert 8 various to `callnatives` by @AsparagusEduardo in [#5172](https://github.com/rh-hideout/pokeemerald-expansion/pull/5172) +* Converted PC strings to `COMPOUND_STRING`s by @fdeblasio in [#5314](https://github.com/rh-hideout/pokeemerald-expansion/pull/5314) +* Cleaned up duplicate dynamic type functions by @AsparagusEduardo in [#5338](https://github.com/rh-hideout/pokeemerald-expansion/pull/5338) +* Removes redundant `moveTargetType` ai function by @AlexOn1ine in [#5354](https://github.com/rh-hideout/pokeemerald-expansion/pull/5354) +* Made `BuildColorMaps` redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289) +* Some strings were switched by @AlexOn1ine in [#5374](https://github.com/rh-hideout/pokeemerald-expansion/pull/5374) +* Switch AI hitsToKO considers Disguise by @Pawkkie in [#5375](https://github.com/rh-hideout/pokeemerald-expansion/pull/5375) +* Cleaned up a bit of code with `GetBattlerPartyData` by @AlexOn1ine in [#5378](https://github.com/rh-hideout/pokeemerald-expansion/pull/5378) +* Minor Gem check optimazation by @AlexOn1ine in [#5401](https://github.com/rh-hideout/pokeemerald-expansion/pull/5401) +* Simplify HP Logic by @AreaZR in [#5403](https://github.com/rh-hideout/pokeemerald-expansion/pull/5403) +* Anger Shell use `saveattacker` by @ghoulslash in [#5409](https://github.com/rh-hideout/pokeemerald-expansion/pull/5409) +* Converted berry and PokeBlock strings to `COMPOUND_STRING`s by @fdeblasio in [#5324](https://github.com/rh-hideout/pokeemerald-expansion/pull/5324) +* Merge item description branch history by @Bassoonian in [#5419](https://github.com/rh-hideout/pokeemerald-expansion/pull/5419) +* Clean up Unseen Fist Check by @AlexOn1ine in [#5420](https://github.com/rh-hideout/pokeemerald-expansion/pull/5420) +* Merge level_caps and ev_caps into one caps file by @kittenchilly in [#5429](https://github.com/rh-hideout/pokeemerald-expansion/pull/5429) +* Removed trailing whitespace pass 10-2-2024 (Upcoming) by @kittenchilly in [#5456](https://github.com/rh-hideout/pokeemerald-expansion/pull/5456) +* Fixed Commander test name by @Bassoonian in [#5458](https://github.com/rh-hideout/pokeemerald-expansion/pull/5458) +* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075) +* Adds padding in `AiLogicData` by @AlexOn1ine in [#5468](https://github.com/rh-hideout/pokeemerald-expansion/pull/5468) +* Simplify `BS_FAINTED_MULTIPLE_1` double battle logic in openpartyscreen by @ghoulslash in [#5435](https://github.com/rh-hideout/pokeemerald-expansion/pull/5435) +* Removes duplicate code in AI functions by @AlexOn1ine in [#5457](https://github.com/rh-hideout/pokeemerald-expansion/pull/5457) +* `ShouldPivot` type cleanup by @Pawkkie in [#5441](https://github.com/rh-hideout/pokeemerald-expansion/pull/5441) +* Turn item hold effects into an enum by @Bassoonian in [#5498](https://github.com/rh-hideout/pokeemerald-expansion/pull/5498) +* Unify `GetBattlerAbility`/`TerrainAffected` to remove duplicate ai function by @AlexOn1ine in [#5497](https://github.com/rh-hideout/pokeemerald-expansion/pull/5497) +* Clean up Shedinja code by @Bassoonian in [#5501](https://github.com/rh-hideout/pokeemerald-expansion/pull/5501) +* Clean up `scrcmd` PR by @Bassoonian in [#5511](https://github.com/rh-hideout/pokeemerald-expansion/pull/5511) +* Removes Crit Chance preproc by @AlexOn1ine in [#5520](https://github.com/rh-hideout/pokeemerald-expansion/pull/5520) +* Removed agbcc screenshots from gitignore by @Bassoonian in [#5538](https://github.com/rh-hideout/pokeemerald-expansion/pull/5538) +* Removed unnecessary `gBattlerAttacker` usage by @AlexOn1ine in [#5554](https://github.com/rh-hideout/pokeemerald-expansion/pull/5554) +* Removed remaining line breaks from #3240 + Prefix wrap fix by @AsparagusEduardo in [#5556](https://github.com/rh-hideout/pokeemerald-expansion/pull/5556) +* More post-#3240 cleanup by @kittenchilly in [#5593](https://github.com/rh-hideout/pokeemerald-expansion/pull/5593) +* Renamed folders and symbols to match species defines by @AsparagusEduardo in [#5581](https://github.com/rh-hideout/pokeemerald-expansion/pull/5581) + - Also: + - Burmy and Wormadam footprints were in a `plant` subfolder. They have been moved to the species root folder + - Paldean Wooper's subfolder was named `wooper_paldean` instead of just `paldean`. This has been corrected. + - Zen Mode Galarian Darmanitan's folder was located in `darmanitan/galarian/zen_mode`. This has been corrected to `darmanitan/galar_zen`, alongside Galarian Standard Mode's `darmanitan/galar_standard`. + - Also updated Ogerpon's folders similarly. + - Renamed `SPECIES_PIKACHU_PARTNER_CAP` to `SPECIES_PIKACHU_PARTNER`. +* Minor `BattleStruct` clean up by @AlexOn1ine in [#5585](https://github.com/rh-hideout/pokeemerald-expansion/pull/5585) +* Fixed a ball update oversight by @Bassoonian in [#5609](https://github.com/rh-hideout/pokeemerald-expansion/pull/5609) +* `AI_FLAG_ACE_POKEMON` takes into account separate trainers by @GhoulMage and @/uvula on Discord noted the weird behaviour in [#5608](https://github.com/rh-hideout/pokeemerald-expansion/pull/5608) + - Fix for the AI not considering both trainers Ace Pokémons in double battles with `AI_FLAG_ACE_POKEMON`. +* Moves that deal a Fixed amount don't need AI handling by @AlexOn1ine in [#5614](https://github.com/rh-hideout/pokeemerald-expansion/pull/5614) +* Combines `CalculateMoveDamage` arguments into a struct by @AlexOn1ine in [#5570](https://github.com/rh-hideout/pokeemerald-expansion/pull/5570) +* Follow up for #5570 by @AlexOn1ine in [#5625](https://github.com/rh-hideout/pokeemerald-expansion/pull/5625) +* `AI_CalcDamage` clean up by @AlexOn1ine in [#5629](https://github.com/rh-hideout/pokeemerald-expansion/pull/5629) +* Convert 3 variouses to `callnatives` by @AlexOn1ine in [#5646](https://github.com/rh-hideout/pokeemerald-expansion/pull/5646) +* Convert `gBattleStringsTable` to `COMPOUND_STRING`s by @AsparagusEduardo in [#5649](https://github.com/rh-hideout/pokeemerald-expansion/pull/5649) +* Added merged placeholder text for trainer name with class by @kittenchilly in [#5622](https://github.com/rh-hideout/pokeemerald-expansion/pull/5622) +* Cleans up Primal Reversion code by @AlexOn1ine in [#5659](https://github.com/rh-hideout/pokeemerald-expansion/pull/5659) +* Critical Hit documentation and distorted match up struct switch by @AlexOn1ine in [#5665](https://github.com/rh-hideout/pokeemerald-expansion/pull/5665) +* Changes name of `B_SCR_NAME_WITH_PREFIX` by @AlexOn1ine in [#5675](https://github.com/rh-hideout/pokeemerald-expansion/pull/5675) +* Removes redundant Decorate check by @AlexOn1ine in [#5696](https://github.com/rh-hideout/pokeemerald-expansion/pull/5696) +* Changes taget bit of Flower Shield by @AlexOn1ine in [#5698](https://github.com/rh-hideout/pokeemerald-expansion/pull/5698) +* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547) + - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1. + +## 🧪 Test Runner 🧪 +### Changed +* Fixed Commander test name by @Bassoonian in [#5458](https://github.com/rh-hideout/pokeemerald-expansion/pull/5458) +* `ShouldSwitchIfGameStatePrompt` Tests by @Pawkkie in [#5462](https://github.com/rh-hideout/pokeemerald-expansion/pull/5462) +* Added various tests, add `RNG_RANDOM_TARGET` by @ghoulslash in [#5438](https://github.com/rh-hideout/pokeemerald-expansion/pull/5438) +* Added Costar Tests, Download Test for Doubles by @ghoulslash in [#5526](https://github.com/rh-hideout/pokeemerald-expansion/pull/5526) +* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549) + - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it. Also: + - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP` + - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP` +* Healer ability tests by @Pawkkie in [#5559](https://github.com/rh-hideout/pokeemerald-expansion/pull/5559) +* Mark all tests as used by @mrgriffin in [#5531](https://github.com/rh-hideout/pokeemerald-expansion/pull/5531) + +### Fixed +* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466) + +## 📚 Documentation 📚 +* `DoBattleIntro` state documentation by @AsparagusEduardo and @ShinyDragonHunter in [#5231](https://github.com/rh-hideout/pokeemerald-expansion/pull/5231) +* Deprecate MMBN Names by @pkmnsnfrn in [#5240](https://github.com/rh-hideout/pokeemerald-expansion/pull/5240) +* `AI_FLAG_SETUP_FIRST_TURN` Rename and Clarifications by @Pawkkie in [#5310](https://github.com/rh-hideout/pokeemerald-expansion/pull/5310) +* Added Composite AI Flags to Docs by @Pawkkie in [#5349](https://github.com/rh-hideout/pokeemerald-expansion/pull/5349) +* Updated the new pokemon tutorial for 1.10 by @hedara90 in [#5721](https://github.com/rh-hideout/pokeemerald-expansion/pull/5721) + - Some changes compared to previous. + +## New Contributors +* @SombrAbsol made their first contribution in [#4958](https://github.com/rh-hideout/pokeemerald-expansion/pull/4958) +* @Galaxeeh made their first contribution in [#5084](https://github.com/rh-hideout/pokeemerald-expansion/pull/5084) +* @Flash1Lucky made their first contribution in [#5269](https://github.com/rh-hideout/pokeemerald-expansion/pull/5269) +* @GhoulMage made their first contribution in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547) + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.9.4...expansion/1.10.0 + + + diff --git a/docs/changelogs/1.9.x/1.9.4.md b/docs/changelogs/1.9.x/1.9.4.md new file mode 100644 index 000000000000..2a41988bd466 --- /dev/null +++ b/docs/changelogs/1.9.x/1.9.4.md @@ -0,0 +1,201 @@ +# Version 1.9.4 + +```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.9.4`. +``` + +## 🌋 IMPORTANT 🌋 +- This update integrates pret's latest Makefile changes, which rearranges the entire file in order to speed up compilation times overall. If you did any changes to it (such as installing Poryscript) and are having issues resolving the conflicts, keep expansion's version of Makefile and reapply your changes afterwards. + +## 🧬 General 🧬 +### Fixed +* Fixed alignment errors in `EWRAM_INIT` and friends when using u8, u16, etc. by @aronson in [#5512](https://github.com/rh-hideout/pokeemerald-expansion/pull/5512) +* Update test LD script to respect 4 byte data section alignment by @aronson in [#5517](https://github.com/rh-hideout/pokeemerald-expansion/pull/5517) +* Fixed Missing `string_util.h` include in `mini_printf.c` by @mrgriffin in [#5572](https://github.com/rh-hideout/pokeemerald-expansion/pull/5572) +* Fixed unnecessary dependency scanning for test build and test rom names by @ravepossum in [#5594](https://github.com/rh-hideout/pokeemerald-expansion/pull/5594) +* Fixed makefile: dependencies for `map_group_count.h` by @SBird1337 in [#5648](https://github.com/rh-hideout/pokeemerald-expansion/pull/5648) + - Fixes an issue that caused the build to fail on updates to `src/debug.c` due to mismatched dependency. + +## 🗺️ Overworld 🗺️ +### Changed +* Followers sprite fixes by @Cafeei in [#5669](https://github.com/rh-hideout/pokeemerald-expansion/pull/5669) +* Follower fixes, Melmetal, Patrat, Woobat by @hedara90 in [#5685](https://github.com/rh-hideout/pokeemerald-expansion/pull/5685) +* Fixed Farfetch'd overworld sprite by @hedara90 in [#5711](https://github.com/rh-hideout/pokeemerald-expansion/pull/5711) + +### Fixed +* Fixed Berry mutations always generating a Persim Berry by @Bassoonian in [#5504](https://github.com/rh-hideout/pokeemerald-expansion/pull/5504) + +## 🐉 Pokémon 🐉 +### Changed +* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547) + - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1. +* PokeCommunity sprites batch (October) by @kittenchilly in [#5655](https://github.com/rh-hideout/pokeemerald-expansion/pull/5655) +* Followers sprite fixes by @Cafeei in [#5669](https://github.com/rh-hideout/pokeemerald-expansion/pull/5669) +* Follower fixes, Melmetal, Patrat, Woobat by @hedara90 in [#5685](https://github.com/rh-hideout/pokeemerald-expansion/pull/5685) +* Fixed Farfetch'd overworld sprite by @hedara90 in [#5711](https://github.com/rh-hideout/pokeemerald-expansion/pull/5711) + +### Fixed +* Fixed `P_FRIENDSHIP_EVO_THRESHOLD` not checking for Gen 8 by @kittenchilly in [#5503](https://github.com/rh-hideout/pokeemerald-expansion/pull/5503) +* Fixed HGSS dex search printing wrong mon after selecting evos by @ravepossum in [#5552](https://github.com/rh-hideout/pokeemerald-expansion/pull/5552) +* Fixed 64px uncompressed followers by @hedara90 in [#5601](https://github.com/rh-hideout/pokeemerald-expansion/pull/5601) +* Deoxys Sprite/Animation Fixes by @SarnPoke in [#5603](https://github.com/rh-hideout/pokeemerald-expansion/pull/5603) +* Fixes Aegislash not reverting back by @AlexOn1ine in [#5734](https://github.com/rh-hideout/pokeemerald-expansion/pull/5734) + +## ⚔️ Battle General ⚔️ +### Changed +* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604) + +### Fixed +* Fixed Shiny Pokemon not being shiny after transforming with a gimmick by @hedara90 in [#5573](https://github.com/rh-hideout/pokeemerald-expansion/pull/5573) +* Handle showdowns apostrophe the same way as ASCII apostrophe by @cawtds in [#5712](https://github.com/rh-hideout/pokeemerald-expansion/pull/5712) +* Fixes Misty Terrain displaying wrong message by @AlexOn1ine in [#5742](https://github.com/rh-hideout/pokeemerald-expansion/pull/5742) +* Fixes Dynamax dynamic move type by @AlexOn1ine in [#5739](https://github.com/rh-hideout/pokeemerald-expansion/pull/5739) + +## 🤹 Moves 🤹 +### Changed +* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604) +* Updated ability popups for Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, fix Doodle/Role Play bugs by @PhallenTree in [#5493](https://github.com/rh-hideout/pokeemerald-expansion/pull/5493) + +### Fixed +* Fixed Follow Me failing in Single Battles for Gen 6/7 config by @AsparagusEduardo in [#5542](https://github.com/rh-hideout/pokeemerald-expansion/pull/5542) +* Fixed `AnimTask_HorizontalShake` uses for shaking screen in battle anims by @ghoulslash in [#5562](https://github.com/rh-hideout/pokeemerald-expansion/pull/5562) +* Fixed weather genie move anims and Springtide Storm targets by @ravepossum in [#5553](https://github.com/rh-hideout/pokeemerald-expansion/pull/5553) +* Fixes Magic Guard not preventing Salt Cure by @AlexOn1ine in [#5583](https://github.com/rh-hideout/pokeemerald-expansion/pull/5583) +* Fixes Dragon Tail using the effect twice during a Parental Bond attack by @AlexOn1ine in [#5630](https://github.com/rh-hideout/pokeemerald-expansion/pull/5630) +* Fixes Magic Coat message by @AlexOn1ine in [#5645](https://github.com/rh-hideout/pokeemerald-expansion/pull/5645) +* Fixes Take heart by @AlexOn1ine in [#5658](https://github.com/rh-hideout/pokeemerald-expansion/pull/5658) +* Fixed Floral Healing anim by @AlexOn1ine in [#5733](https://github.com/rh-hideout/pokeemerald-expansion/pull/5733) +* Fixes Population Bomb / Triple Kick missing message by @AlexOn1ine in [#5747](https://github.com/rh-hideout/pokeemerald-expansion/pull/5747) +* Changes Max Phantasm move anim script call by @AlexOn1ine in [#5737](https://github.com/rh-hideout/pokeemerald-expansion/pull/5737) +* Fixes Partner targeting and Acupressure/Ally Switch interaction by @AlexOn1ine in [#5446](https://github.com/rh-hideout/pokeemerald-expansion/pull/5446) +* Revival Blessing fixes + Using Lunar Blessing's animation by @ghoulslash in [#5490](https://github.com/rh-hideout/pokeemerald-expansion/pull/5490) +* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663) +* Added Minimize interaction to Supercell Slam by @hedara90 in [#5713](https://github.com/rh-hideout/pokeemerald-expansion/pull/5713) + +## 🎭 Abilities 🎭 +### Changed +* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604) + +### Fixed +* Adds tests and Costar fix from PR #5526 by @AlexOn1ine in [#5529](https://github.com/rh-hideout/pokeemerald-expansion/pull/5529) +* Fixes Red Card / Eject Pack interaction with Emergency Exit by @AlexOn1ine in [#5657](https://github.com/rh-hideout/pokeemerald-expansion/pull/5657) +* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663) +* Mimicry updates typing with `RemoveAllTerrains()` by @AERDU in [#5666](https://github.com/rh-hideout/pokeemerald-expansion/pull/5666) +* Updated ability popups for Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, fix Doodle/Role Play bugs by @PhallenTree in [#5493](https://github.com/rh-hideout/pokeemerald-expansion/pull/5493) +* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663) +* Fixes Ice Face regression by @AlexOn1ine in [#5678](https://github.com/rh-hideout/pokeemerald-expansion/pull/5678) +* Fixes Neutralizing Gas crashes + adds missing interaction, Regenerator small fix by @PhallenTree in [#5694](https://github.com/rh-hideout/pokeemerald-expansion/pull/5694) + +## 🧶 Items 🧶 +### Changed +* Removes duplicate Booster Energy code by @AlexOn1ine in [#5656](https://github.com/rh-hideout/pokeemerald-expansion/pull/5656) + +### Fixed +* Fixes Red Card / Eject Pack interaction with Emergency Exit by @AlexOn1ine in [#5657](https://github.com/rh-hideout/pokeemerald-expansion/pull/5657) +* Fixes Red Card / Eject Pack interaction by @AlexOn1ine in [#5724](https://github.com/rh-hideout/pokeemerald-expansion/pull/5724) +* Fixes gems triggering on confusion damage by @AlexOn1ine in [#5723](https://github.com/rh-hideout/pokeemerald-expansion/pull/5723) +* Fixes Kee Maranga and Enigma Berry by @AlexOn1ine in [#5727](https://github.com/rh-hideout/pokeemerald-expansion/pull/5727) +* Fixes Blunder Policy by @AlexOn1ine in [#5722](https://github.com/rh-hideout/pokeemerald-expansion/pull/5722) +* Fixes Rusted Shield/Sword allowed to be Knocked Off from Zamazenta/Zacian by @iriv24 in [#5750](https://github.com/rh-hideout/pokeemerald-expansion/pull/5750) + +## 🤖 Battle AI 🤖 +### Fixed +* Fixed certain move data being cleared on turn end by @Pawkkie and @AlexOn1ine in [#5488](https://github.com/rh-hideout/pokeemerald-expansion/pull/5488) +* Global is used instead of passed var by @AlexOn1ine in [#5546](https://github.com/rh-hideout/pokeemerald-expansion/pull/5546) +* Fixes `dynamicMoveType` global not being reset during AI calcs by @AlexOn1ine in [#5628](https://github.com/rh-hideout/pokeemerald-expansion/pull/5628) + +## 🧹 Other Cleanup 🧹 +* Remove one redundant call of `SetAiLogicDataForTurn` in `DoBattleIntro` by @AlexOn1ine in [#5491](https://github.com/rh-hideout/pokeemerald-expansion/pull/5491) +* Cleanup extraneous function in `battle_anim.h` by @hedara90 in [#5506](https://github.com/rh-hideout/pokeemerald-expansion/pull/5506) +* Add newline to move relearner string by @Bassoonian in [#5523](https://github.com/rh-hideout/pokeemerald-expansion/pull/5523) +* Fixed 10,000,000 Volt Thunderbolt name by @AsparagusEduardo in [#5533](https://github.com/rh-hideout/pokeemerald-expansion/pull/5533) +* Added constant to expansion inclusive copyright magic number by @pkmnsnfrn in [#5413](https://github.com/rh-hideout/pokeemerald-expansion/pull/5413) +* Centralise AI Tests trainer name by @Bassoonian in [#5532](https://github.com/rh-hideout/pokeemerald-expansion/pull/5532) +* Remove now outdated information from readme by @Bassoonian in [#5548](https://github.com/rh-hideout/pokeemerald-expansion/pull/5548) +* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547) + - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1. +* Shed Skin chance fix by @Pawkkie in [#5558](https://github.com/rh-hideout/pokeemerald-expansion/pull/5558) +* Restore test file dependencies so they're rebuilt properly by @ravepossum in [#5617](https://github.com/rh-hideout/pokeemerald-expansion/pull/5617) +* Improve `SEND_OUT` error message; require Speed for all battlers by @mrgriffin in [#5631](https://github.com/rh-hideout/pokeemerald-expansion/pull/5631) +* Removes duplicate Booster Energy code by @AlexOn1ine in [#5656](https://github.com/rh-hideout/pokeemerald-expansion/pull/5656) +* Wrong assumtion in dauntless_shield.c by @AlexOn1ine in [#5692](https://github.com/rh-hideout/pokeemerald-expansion/pull/5692) + +## 🧪 Test Runner 🧪 +### Added +* Add curious medicine test by @ghoulslash in [#5540](https://github.com/rh-hideout/pokeemerald-expansion/pull/5540) +* Tests: detect task leaks by @mrgriffin in [#5528](https://github.com/rh-hideout/pokeemerald-expansion/pull/5528) + +### Changed +* Add text width tests for move, ability, item, and pokedex descriptions by @kittenchilly in [#5505](https://github.com/rh-hideout/pokeemerald-expansion/pull/5505) +* Centralise AI Tests trainer name by @Bassoonian in [#5532](https://github.com/rh-hideout/pokeemerald-expansion/pull/5532) +* Add basic Steam Engine, Guard Dog Tests by @ghoulslash in [#5569](https://github.com/rh-hideout/pokeemerald-expansion/pull/5569) +* Fixed damage test by @GhoulMage and @mrgriffin for teaching me pokeemerald-expansion tests in [#5574](https://github.com/rh-hideout/pokeemerald-expansion/pull/5574) +* Fallback `memmem` implementation by @mrgriffin in [#5561](https://github.com/rh-hideout/pokeemerald-expansion/pull/5561) +* Hydra: Support `%p` in test summaries by @mrgriffin in [#5626](https://github.com/rh-hideout/pokeemerald-expansion/pull/5626) +* Improve `SEND_OUT` error message; require Speed for all battlers by @mrgriffin in [#5631](https://github.com/rh-hideout/pokeemerald-expansion/pull/5631) +* Check that `PASSES_RANDOMLY` affected a `Random` call by @mrgriffin in [#5635](https://github.com/rh-hideout/pokeemerald-expansion/pull/5635) +* Wrong assumtion in dauntless_shield.c by @AlexOn1ine in [#5692](https://github.com/rh-hideout/pokeemerald-expansion/pull/5692) + +### Fixed +* Update test LD script to respect 4 byte data section alignment by @aronson in [#5517](https://github.com/rh-hideout/pokeemerald-expansion/pull/5517) +* Adds tests and Costar fix from PR #5526 by @AlexOn1ine in [#5529](https://github.com/rh-hideout/pokeemerald-expansion/pull/5529) +* Fixed broken Starting Terrain test by @hedara90 in [#5582](https://github.com/rh-hideout/pokeemerald-expansion/pull/5582) + +## 📚 Documentation 📚 +* Add changelog header in PR template to aid automation by @AsparagusEduardo in [#5539](https://github.com/rh-hideout/pokeemerald-expansion/pull/5539) +* Added compressed OW mon VRAM notice in config file by @AsparagusEduardo in [#5599](https://github.com/rh-hideout/pokeemerald-expansion/pull/5599) +* Update `README.md` to link to `INSTALL.md` by @Pawkkie in [#5720](https://github.com/rh-hideout/pokeemerald-expansion/pull/5720) +* Fixes minor move desc errors by @AlexOn1ine in [#5728](https://github.com/rh-hideout/pokeemerald-expansion/pull/5728) + +## 📦 Branch Synchronisation 📦 +### pret +* 15th of October in [#5527](https://github.com/rh-hideout/pokeemerald-expansion/pull/5527) + * Slight storage system documentation by @luckytyphlosion in [pret#2024](https://github.com/pret/pokeemerald/pull/2024) + * Clean up defines lacking spaces by @Bassoonian in [pret#2025](https://github.com/pret/pokeemerald/pull/2025) + * UB fix in battle_transition.c by @cawtds in [pret#2007](https://github.com/pret/pokeemerald/pull/2007) + * preproc: support arbitrary expressions in enums by @mrgriffin in [pret#2026](https://github.com/pret/pokeemerald/pull/2026) + * [Build System Rewrite] Refactored `Makefile` by @Icedude907 in [pret#1950](https://github.com/pret/pokeemerald/pull/1950) + * Fixed incorrect point macros in contest_ai_script.inc by @NTx86 in [pret#2028](https://github.com/pret/pokeemerald/pull/2028) + * [Build System Rewrite] Massive build speed improvement via scaninc changes by @Icedude907 in [pret#1954](https://github.com/pret/pokeemerald/pull/1954) + * [Build System Rewrite] Improved audio rules by @Icedude907 in [pret#1957](https://github.com/pret/pokeemerald/pull/1957) + * Update INSTALL.md to state that Windows 8 is no longer supported by Microsoft by @luciofstars in [pret#2029](https://github.com/pret/pokeemerald/pull/2029) + * Update pull_request_template.md to include Discord username update by @luciofstars in [pret#2030](https://github.com/pret/pokeemerald/pull/2030) + * remove ScriptContext_Enable from secret_base.h by @DizzyEggg in [pret#2032](https://github.com/pret/pokeemerald/pull/2032) + * Remove gflib by @Kurausukun in [pret#2033](https://github.com/pret/pokeemerald/pull/2033) + * Minor toolchain fixes by @GriffinRichards in [pret#2031](https://github.com/pret/pokeemerald/pull/2031) + * Bugfix for cable car hikerGraphicsIds array by @Scyrous in [pret#2039](https://github.com/pret/pokeemerald/pull/2039) + * Remove explicit symbol sizes in sym_common.txt by @GriffinRichards in [pret#2038](https://github.com/pret/pokeemerald/pull/2038) + * Ignore mGBA screenshots by @Jaizu in [pret#2041](https://github.com/pret/pokeemerald/pull/2041) + * Replaced copyright magic numbers in intro.c with constants by @pkmnsnfrn in [pret#2035](https://github.com/pret/pokeemerald/pull/2035) + * Fixed typo: | should be || in Task_TryFieldPoisonWhiteOut by @AreaZR in [pret#2044](https://github.com/pret/pokeemerald/pull/2044) + * [preproc] support C23 enum underlying type syntax by @mrgriffin in [pret#2043](https://github.com/pret/pokeemerald/pull/2043) + * Fixed deleting files with dependency files by @mid-kid in [pret#2045](https://github.com/pret/pokeemerald/pull/2045) + * Remove unnecessary looping for rule generation and unroll macros by @mid-kid in [pret#2046](https://github.com/pret/pokeemerald/pull/2046) + * Get rid of common syms by @luckytyphlosion in [pret#2040](https://github.com/pret/pokeemerald/pull/2040) + * Bugfix for cable car hikerGraphicsIds array by @Scyrous in [pret#2039](https://github.com/pret/pokeemerald/pull/2039) + * UB fix in battle_transition.c by @cawtds in [pret#2007](https://github.com/pret/pokeemerald/pull/2007) + * Fixed typo: | should be || in Task_TryFieldPoisonWhiteOut by @AreaZR in [pret#2044](https://github.com/pret/pokeemerald/pull/2044) + * Get rid of common syms by @luckytyphlosion in [pret#2040](https://github.com/pret/pokeemerald/pull/2040) + * Fixed incorrect point macros in contest_ai_script.inc by @NTx86 in [pret#2028](https://github.com/pret/pokeemerald/pull/2028) +* 5th of November in [#5644](https://github.com/rh-hideout/pokeemerald-expansion/pull/5644) + * Added define value for bard sound length by @fdeblasio in [pret#2052](https://github.com/pret/pokeemerald/pull/2052) + * Silence 'Nothing to be done for generated' messages by @GriffinRichards in [pret#2059](https://github.com/pret/pokeemerald/pull/2059) + * Lay out emerald version png horizontally by @GriffinRichards in [pret#2062](https://github.com/pret/pokeemerald/pull/2062) +* 29 of November in [#5736](https://github.com/rh-hideout/pokeemerald-expansion/pull/5736) + * Remove usage of gHeap in sSpritePalettes_ContestantsTurnBlinkEffect by @Lactozilla in [pret#2064](https://github.com/pret/pokeemerald/pull/2064) + * BUGFIX: Fix Counter and Mirror Coat checking the wrong category by @surtr-games in [pret#2066](https://github.com/pret/pokeemerald/pull/2066) + * Add TRY_DRAW_SPOT_PIXEL by @GriffinRichards in [pret#2055](https://github.com/pret/pokeemerald/pull/2055) + * Added extra encoded character support by @AsparagusEduardo in [pret#2050](https://github.com/pret/pokeemerald/pull/2050) +### merrp's followers +* Merrp merge (12th of October) by @Bassoonian in [#5514](https://github.com/rh-hideout/pokeemerald-expansion/pull/5514) + - d80190fe105eee12bbf74ae29647ac909084d35c fix: Dig in Sealed Chamber no longer freezes follower. + +## New Contributors +* @AERDU made their first contribution in [#5666](https://github.com/rh-hideout/pokeemerald-expansion/pull/5666) + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.9.3...expansion/1.9.4 + + + diff --git a/docs/tutorials/how_to_new_pokemon_1_10_0.md b/docs/tutorials/how_to_new_pokemon_1_10_0.md new file mode 100644 index 000000000000..f6eaedee9996 --- /dev/null +++ b/docs/tutorials/how_to_new_pokemon_1_10_0.md @@ -0,0 +1,1163 @@ + +This is a modified version of [the original tutorial about adding new Pokémon species available in Pokeemerald's wiki](https://github.com/pret/pokeemerald/wiki/How-to-add-a-new-Pokémon-species). + +Despite the persistent rumors about an incredibly strong third form of Mew hiding somewhere, it actually wasn't possible to catch it... OR WAS IT? +In this tutorial, we will add a new Pokémon species to the game. + +## IMPORTANT: This tutorial applies to 1.10.x versions. +- [Version 1.9.x](how_to_new_pokemon_1_9_0.md) +- [Version 1.8.x](how_to_new_pokemon_1_8_0.md) +- [Version 1.7.x](how_to_new_pokemon_1_7_0.md) +- [Version 1.6.x](how_to_new_pokemon_1_6_0.md) + +# Changes compared to vanilla +The main things that the Expansion changes are listed here. +* Still Front Pics *(`gMonStillFrontPic_YourPokemon`)* and by extension `src/anim_mon_front_pics.c` have been removed. +* `src/data/pokemon/cry_ids.h` doesn't exist anymore. +* You have 6 icon palettes available instead of the base 3. +* Most tables that use `SPECIES_x` as indexes have been moved to `gSpeciesInfo`. + +# Content +* [Useful resources](#useful-resources) +* [The Data - Part 1](#the-data---part-1) + * [1. Declare a species constant](#1-Declare-a-species-constant) + * [2. `SpeciesInfo`'s structure](#2-speciesinfos-structure) + * [3. Define its basic species information](#3-define-its-basic-species-information) + * [4. Species Name](#4-species-name) + * [5. Define its cry](#5-define-its-cry) + * [6. Define its Pokédex entry](#6-define-its-pokédex-entry) +* [The Graphics](#the-graphics) + * [1. Edit the sprites](#1-edit-the-sprites) + * [2. Add the sprites to the rom](#2-add-the-sprites-to-the-rom) + * [3. Add the animations to the rom](#3-add-the-animations-to-the-rom) + * [4. Linking graphic information to our Pokémon](#4-linking-graphic-information-to-our-pokémon) +* [The Data - Part 2](#the-data---part-2) + * [1. Species Flags](#1-species-flags) + * [2. Delimit the moveset](#2-delimit-the-moveset) + * [3. Define the Evolutions](#3-define-the-evolutions) + * [4. Make it appear!](#4-make-it-appear) +* [Optional data](#optional-data) + * [1. Form tables](#1-form-tables) + * [2. Form change tables](#2-form-change-tables) + * [3. Gender differences](#3-gender-differences) + * [4. Overworld Data](#4-overworld-data) + +# Useful resources +You can open a sprite debug menu by pressing `Select` in a Pokémon's summary screen outside of battle. + +![mGBA_6WOo1TSlsn](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/0c625cd8-8f89-4bc8-a285-b10a420a8f6d) + + +# The Data - Part 1 + +Our plan is as simple as it is brilliant: clone Mewtwo... and make it even stronger! + +## 1. Declare a species constant + +Our first step towards creating a new digital lifeform is to define its own species constant. + +Edit [include/constants/species.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/species.h): + +```diff + #define SPECIES_NONE 0 + #define SPECIES_BULBASAUR 1 + ... + #define SPECIES_MIMIKYU_BUSTED_TOTEM 1523 + #define SPECIES_MIMIKYU_TOTEM_BUSTED SPECIES_MIMIKYU_BUSTED_TOTEM ++#define SPECIES_MEWTHREE 1524 + +-#define SPECIES_EGG (SPECIES_MIMIKYU_BUSTED_TOTEM + 1) ++#define SPECIES_EGG (SPECIES_MEWTHREE + 1) + + #define NUM_SPECIES SPECIES_EGG +``` +This number is stored in a Pokémon's save structure. These should generally never change, otherwise your saved Pokémon species will change as well. + +We add this at the end so that no existing species change Id and so that we don't have to renumber everything after it. + +Now, let's see how it looks in-game! + +![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/dc15b0ba-a4bd-4f4e-9658-2dff73a11f79) + +Hmmm, something's not right... + +Oh, I know! We need to add the rest of the data! Normally, the vanilla game would crash if we try to look up anything about Mewthree in this state, but the expansion defaults all of its data to `SPECIES_NONE`. + +Now, let's see what needs to be done. + +## 2. `SpeciesInfo`'s structure +Now, to better understand Mewthree, we also need to understand Mew. Let's look at its data. +```diff + [SPECIES_MEW] = + { + .baseHP = 100, + .baseAttack = 100, + .baseDefense = 100, + .baseSpeed = 100, + .baseSpAttack = 100, + .baseSpDefense = 100, + .types = MON_TYPES(TYPE_PSYCHIC), + .catchRate = 45, + #if P_UPDATED_EXP_YIELDS >= GEN_8 + .expYield = 300, + #elif P_UPDATED_EXP_YIELDS >= GEN_5 + .expYield = 270, + #else + .expYield = 64, + #endif + .evYield_HP = 3, + .itemCommon = ITEM_LUM_BERRY, + .itemRare = ITEM_LUM_BERRY, + .genderRatio = MON_GENDERLESS, + .eggCycles = 120, + .friendship = 100, + .growthRate = GROWTH_MEDIUM_SLOW, + .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED), + .abilities = { ABILITY_SYNCHRONIZE, ABILITY_NONE, ABILITY_NONE }, + .bodyColor = BODY_COLOR_PINK, + .speciesName = _("Mew"), + .cryId = CRY_MEW, + .natDexNum = NATIONAL_DEX_MEW, + .categoryName = _("New Species"), + .height = 4, + .weight = 40, + .description = COMPOUND_STRING( + "A Mew is said to possess the genes of all\n" + "Pokémon. It is capable of making itself\n" + "invisible at will, so it entirely avoids\n" + "notice even if it approaches people."), + .pokemonScale = 457, + .pokemonOffset = -2, + .trainerScale = 256, + .trainerOffset = 0, + .frontPic = gMonFrontPic_Mew, + .frontPicSize = P_GBA_STYLE_SPECIES_GFX ? MON_COORDS_SIZE(40, 40) : MON_COORDS_SIZE(64, 48), + .frontPicYOffset = P_GBA_STYLE_SPECIES_GFX ? 13 : 9, + .frontAnimFrames = sAnims_Mew, + .frontAnimId = P_GBA_STYLE_SPECIES_GFX ? ANIM_SWING_CONVEX : ANIM_ZIGZAG_SLOW, + .enemyMonElevation = P_GBA_STYLE_SPECIES_GFX ? 8 : 11, + .backPic = gMonBackPic_Mew, + .backPicSize = P_GBA_STYLE_SPECIES_GFX ? MON_COORDS_SIZE(48, 48) : MON_COORDS_SIZE(64, 64), + .backPicYOffset = P_GBA_STYLE_SPECIES_GFX ? 8 : 0, + .backAnimId = BACK_ANIM_CONCAVE_ARC_SMALL, + .palette = gMonPalette_Mew, + .shinyPalette = gMonShinyPalette_Mew, + .iconSprite = gMonIcon_Mew, + .iconPalIndex = 0, + SHADOW(0, 13, SHADOW_SIZE_S) + FOOTPRINT(Mew) + OVERWORLD( + sPicTable_Mew, + SIZE_32x32, + SHADOW_SIZE_M, + TRACKS_NONE, + gOverworldPalette_Mew, + gShinyOverworldPalette_Mew + ) + .isMythical = TRUE, + .isFrontierBanned = TRUE, + .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, + .levelUpLearnset = sMewLevelUpLearnset, + .teachableLearnset = sMewTeachableLearnset, + }, +``` + +That's a lot of stuff! But don't worry, we'll go through it step by step throughout the tutorial +(and it's miles better than having this same data through 20+ files like it used to be). + +We'll start by adding the self-explanatory data that's also present in pret's vanilla structure: + +## 3. Define its basic species information +Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/species_info.h): +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + [SPECIES_NONE] = {0}, + ... + + [SPECIES_EGG] = + { + FRONT_PIC(Egg, 24, 24), + .frontPicYOffset = 20, + .backPic = gMonFrontPic_Egg, + .backPicSize = MON_COORDS_SIZE(24, 24), + .backPicYOffset = 20, + .palette = gMonPalette_Egg, + .shinyPalette = gMonPalette_Egg, + ICON(Egg, 1), + }, + ++ [SPECIES_MEWTHREE] = ++ { ++ .baseHP = 106, ++ .baseAttack = 150, ++ .baseDefense = 70, ++ .baseSpeed = 140, ++ .baseSpAttack = 194, ++ .baseSpDefense = 120, ++ .types = MON_TYPES(TYPE_PSYCHIC), ++ .catchRate = 3, ++ .expYield = 255, ++ .evYield_SpAttack = 3, ++ .genderRatio = MON_GENDERLESS, ++ .eggCycles = 120, ++ .friendship = 0, ++ .growthRate = GROWTH_SLOW, ++ .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED), ++ .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE }, ++ .bodyColor = BODY_COLOR_PURPLE, ++ }, + }; +``` + +The `.` is the structure reference operator in C to refer to the member object of the structure SpeciesInfo. + +- `baseHP`, `baseAttack`, `baseDefense`, `baseSpeed`, `baseSpAttack` and `baseSpDefense` are the base stats. They can't go higher than 255. +- `types` is using the macro `MON_TYPES` as a helper function for formatting so that only one type has to be input for species with a single type. + - To add a species with 2 types, use the format `MON_TYPES(TYPE_PSYCHIC, TYPE_NORMAL)`. +- `catchRate` is how likely it is to catch a Pokémon, the lower the value, the harder it is to catch. Legendaries generally have a catch rate of 3, so we put that here. +- `expYield` is the base amount of experience that a Pokémon gives when defeated/caught. In vanilla, this value caps at 255, but we've increased it to a maximum of 65535 accomodate later gen's higher experience yields. (The highest official value is Blissey's with 608, so going beyond this point may cause exponential gains that could break the system 😱) + - If you noticed, Mew's had some `#if`s, `#elif`s and `#endif` around it. This is because its yield has changed over time, and we let you choose which ones you want. This is not relevant to our Mewthree however, so we can just put a single `.expYield = 255,` line here. +- `evYield_HP`, `evYield_Attack`, `evYield_Defense`, `evYield_Speed`, `evYield_SpAttack` and `evYield_SpDefense` are how many EVs does the Pokémon give when they're caught. Each of these fields can have a value of 3 at most. Officially, no Pokémon give out more than 3 EVs total, with them being determined by their evolution stage (eg, Pichu, Pikachu and Raichu give 1, 2 and 3 Speed EVs respectively), and they tend to be associated with its higher stats. Since our Mewthree is a Special Attack monster, we'll be consistent and make it give out 3 Special Attack EVs, but you're always free to assign whatever you feel like :) + - Notice that the other `evYield` fields are not there. In C, numbers in a struct default to 0, so if we don't specify them, they'll be 0 all around! Less lines to worry about :D +- `itemCommon` and `itemRare` are used to determine what items is the Pokémon holding when encountering it in the wild. + - 50% for `itemCommon` and 5% for `itemRare` (boosted to 60%/20% when the first mon in the party has Compound Eyes or Super Luck) + - If they're both set as the same item, the item has a 100% chance of appearing. +- `genderRatio` is a fun one. + - There are 4 ways of handling this + - `PERCENT_FEMALE` is what most Pokémon use, where you define how likely it's gonna be female. It supports decimals, so you can put `PERCENT_FEMALE(12.5)` to have a 1 in 8 chance of your mon to be female. + - `MON_MALE` guarantees that all mon of this species will be male (eg. Tauros) + - `MON_FEMALE` guarantees that all mon of this species will be female (eg. Miltank) + - `MON_GENDERLESS` makes your species genderless, unable to breed with anything but Ditto to produce eggs. Most Legendaries are this, so we'll be chosing this as Mewthree's gender ratio. + - When working with evolution lines and don't want their genders to change after evolving, be sure that their gender ratios match their stages and evolution methods. Azurill is the only case where there's a mismatch, causing 1/3 of all Azurill to change from Female to Male. + - You might be wondering why some species have multiple defines for their genders, like `SPECIES_MEOWSTIC_(FE)MALE`. This is because those species have different stats and data from each other, so they're defined internally as different forms with `MON_MALE` and `MON_FEMALE` as gender ratios. If your species evolves depending on its gender and the evolutions have different stats, be sure to apply the correct evolution method! +- `eggCycles` determines how fast an egg of this species will hatch. Doesn't matter much for evolved species or those that can't lay eggs, but we add the field here just in case. +- `friendship` determines the amount of friendship of the mon when you catch it. Most Pokémon use `STANDARD_FRIENDSHIP`, but this creature of chaos does not want to be your friend, starting with 0. +- `growthRate` determines the amounts of experience required to reach each level. Go [here](https://bulbapedia.bulbagarden.net/wiki/Experience) for more info. + - This should be consistent across evolution lines, otherwise levels could change upon evolution. +- `eggGroups` are used for breed compatibility. Most Legendaries and Mythicals have the `EGG_GROUP_NO_EGGS_DISCOVERED` group, and so does our Mewthree. Go [here](https://bulbapedia.bulbagarden.net/wiki/Egg_Group) for more info. + - This is using the helper macro `MON_EGG_GROUPS`. +- `abilities` determines the potential abilites of our species. Notice how I also set the ability to `ABILITY_INSOMNIA`, so our little monster doesn't even need to sleep anymore. You can find the abilities for example here [include/constants/abilities.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/abilities.h). + - When both slot 1 and 2 are defined as not being `ABILITY_NONE`, their starting ability will be decided on a coin flip using their personality. They can later be changed using an Ability Capsule. + - Certain Pokémon such as Zygarde and Rockruff have different forms to add additional abilities. As such, they cannot be changed using an Ability Capsule (though the Zygarde Cube can change Zygarde's ability by changing them to their corresponding form) + - The 3rd slot is for Hidden Abilities. If defined as `ABILITY_NONE`, it will default to Slot 1 (eg. Metapod doesn't have a Hidden Ability, but Caterpie and Butterfree do). Go [here](https://bulbapedia.bulbagarden.net/wiki/Ability#Hidden_Abilities) and [here](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch) for more info. + - If the array is defined as `{ABILITY_1, ABILITY_2}`, the Hidden Ability is set as `ABILITY_NONE`. +- `bodyColor` is used in the Pokédex as a search filter. +- `noFlip` is used in to prevent front sprites from being flipped horizontally and cause weird issues, like Clawitzer's big claw changing sides. + +That's all the basic fields present in vanilla emerald, so now let's take a look at the new fields added by the expansion. + +## 4. Species Name + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .bodyColor = BODY_COLOR_PURPLE, ++ .speciesName = _("Mewthree"), + }, + }; +``` +The `_()` underscore function doesn't really exist - it's a convention borrowed from GNU gettext to let `preproc` know this is text to be converted to the custom encoding used by the Gen 3 Pokemon games. + +## 5. Define its cry + +Time for audio! +We first need to convert an existing audio file to the format supported by the expansion. + +Most formats are supported for conversion, but for simplicity's sake, we're gonna use an mp3 file. + +Now, let's copy the file to the `sound/direct_sound_samples/cries` folder. +Once that's done, let's run the following command: +``` +ffmpeg -i sound/direct_sound_samples/cries/mewthree.mp3 -c:a pcm_s8 -ac 1 -ar 13379 sound/direct_sound_samples/cries/mewthree.aif +``` +This will convert your audio file to .aif, which is what's read by the compiler. + +Let's add the cry to the ROM via [sound/direct_sound_data.inc](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/sound/direct_sound_data.inc). + +```diff +.if P_FAMILY_PECHARUNT == TRUE + .align 2 +Cry_Pecharunt:: + .incbin "sound/direct_sound_samples/cries/pecharunt.bin" +.endif @ P_FAMILY_PECHARUNT + ++ .align 2 ++Cry_Mewthree:: ++ .incbin "sound/direct_sound_samples/cries/mewthree.bin" + +``` + +Then we add the cry ID to [include/constants/cries.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/cries.h): + +```diff +enum { + CRY_NONE, + ... +#if P_FAMILY_TERAPAGOS + CRY_TERAPAGOS, +#endif //P_FAMILY_TERAPAGOS +#if P_FAMILY_PECHARUNT + CRY_PECHARUNT, +#endif //P_FAMILY_PECHARUNT ++ CRY_MEWTHREE, + CRY_COUNT, +}; +``` + +And then link it in [sound/cry_tables.inc](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/sound/cry_tables.inc). `cry_reverse` in particular is for reversed cries used by moves such as Growl. The order of these two tables should match the order of the cry IDs, otherwise they'll be shifted. + +```diff + cry Cry_Terapagos + cry Cry_Pecharunt ++ cry Cry_Mewthree +``` +```diff + cry_reverse Cry_Terapagos + cry_reverse Cry_Pecharunt ++ cry_reverse Cry_Mewthree +``` + +Lastly, we add the cry to our species entry +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .speciesName = _("Mewthree"), ++ .cryId = CRY_MEWTHREE, + }, + }; +``` + +And let's see how it sounds in-game: + +https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/4f7667db-4db9-4bfd-a8dd-ece26f09f327 + +Good! Our monster now has a mighty roar! + +You can now delete the mp3 from the cries folder now once you made sure that the cry sounds like how you want it to. + +## 6. Define its Pokédex entry + +First, we will need to add new index constants for its Pokédex entry. The index constants are divided into the Hoenn Pokédex, which contains all Pokémon native to the Hoenn region, and the National Pokédex containing all known Pokémon, which can be received after entering the hall of fame for the first time. + +Edit [include/constants/pokedex.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/pokedex.h): + +```diff +// National Pokedex order +enum { + NATIONAL_DEX_NONE, + // Kanto + NATIONAL_DEX_BULBASAUR, +... + NATIONAL_DEX_PECHARUNT, ++ NATIONAL_DEX_MEWTHREE, +}; +``` + +```diff + #define KANTO_DEX_COUNT NATIONAL_DEX_MEW + #define JOHTO_DEX_COUNT NATIONAL_DEX_CELEBI + +#if P_GEN_9_POKEMON == TRUE +- #define NATIONAL_DEX_COUNT NATIONAL_DEX_PECHARUNT ++ #define NATIONAL_DEX_COUNT NATIONAL_DEX_MEWTHREE +``` + +Do keep in mind that if you intend to add your new species to the Hoenn Dex, you'll also want to add a `HOENN_DEX` constant for it and give it a `HOENN_TO_NATIONAL` member, like this: + +```diff +// Hoenn Pokedex order +enum { + HOENN_DEX_NONE, + HOENN_DEX_TREECKO, +... + HOENN_DEX_DEOXYS, ++ HOENN_DEX_MEWTHREE, +}; + +- #define HOENN_DEX_COUNT (HOENN_DEX_DEOXYS + 1) ++ #define HOENN_DEX_COUNT (HOENN_DEX_MEWTHREE + 1) +``` + +Edit [src/pokemon.c](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/pokemon.c): + +```diff + const u16 sHoennToNationalOrder[NUM_SPECIES] = // Assigns Hoenn Dex Pokémon (Using National Dex Index) + { + HOENN_TO_NATIONAL(TREECKO), + ... + HOENN_TO_NATIONAL(DEOXYS), ++ HOENN_TO_NATIONAL(MEWTHREE), + }; +``` + +Now we can add the number and entry to our Mewthree: +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .cryId = CRY_MEWTHREE, ++ .natDexNum = NATIONAL_DEX_MEWTHREE, ++ .categoryName = _("New Species"), ++ .height = 15, ++ .weight = 330, ++ .description = COMPOUND_STRING( ++ "The rumors became true.\n" ++ "This is Mew's final form.\n" ++ "Its power level is over 9000.\n" ++ "Has science gone too far?"), ++ .pokemonScale = 256, ++ .pokemonOffset = 0, ++ .trainerScale = 290, ++ .trainerOffset = 2, + }, + }; +``` +![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/3759dd4c-8da5-4b1c-9a50-b9e9d0815e7f) + +The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. + +`height` and `weight` are specified in decimeters and hectograms respectively (which are meters and kilograms multiplied by 10, so 2.5 meters are 25 decimeters). + +In Pokémon Emerald, you can sort the Pokédex by name, height or weight. Apparently, the Pokémon order is hardcoded in the game files and not calculated from their data. Therefore we have to include our new Pokémon species at the right places. While the correct position for the alphabetical order is easy to find, it can become quite tedious for height and weight, so we added comments to the listings in order help out were they should fit. + +Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/pokedex_orders.h): + +```diff + const u16 gPokedexOrder_Alphabetical[] = + { + ... + NATIONAL_DEX_MEW, ++ NATIONAL_DEX_MEWTHREE, + NATIONAL_DEX_MEWTWO, + ... + }; + + const u16 gPokedexOrder_Weight[] = + { + ... + // 72.8 lbs / 33.0 kg + //NATIONAL_DEX_MEWTWO_MEGA_Y, + NATIONAL_DEX_ESCAVALIER, + NATIONAL_DEX_FRILLISH, + NATIONAL_DEX_DURANT, + NATIONAL_DEX_CINDERACE, ++ NATIONAL_DEX_MEWTHREE, + //NATIONAL_DEX_PERSIAN_ALOLAN, + NATIONAL_DEX_TOEDSCOOL, + // 73.4 lbs / 33.3 kg + NATIONAL_DEX_DUGTRIO, + ... + }; + + const u16 gPokedexOrder_Height[] = + { + ... + // 4'11" / 1.5m + ... + NATIONAL_DEX_GLIMMORA, + NATIONAL_DEX_WO_CHIEN, + NATIONAL_DEX_IRON_LEAVES, + NATIONAL_DEX_IRON_BOULDER, ++ NATIONAL_DEX_MEWTHREE, + // 5'03" / 1.6m + ... + }; +``` +![mGBA_lUBfmFEKUx](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/3a8b8a17-759b-486b-9831-deb2f494bd71) + + +# The Graphics +We will start by copying the following files for *Mew* (not Mewtwo) and rename it to `mewthree`. +```sh +cp -r graphics/pokemon/mew/. graphics/pokemon/mewthree +``` +We aren't copying Mewtwo's folder because he has those pesky Mega Evolutions that will get in the way of what we're doing, so our sample will need to be pure from the source. + +## 1. Edit the sprites +Let's edit the sprites. Start your favourite image editor (I recommend Aseprite or its free alternative, Libresprite) and change `anim_front.png` and `back.png` to meet your expectations. + +__Make sure that you are using the indexed mode and you have limited yourself to 15 colors!__ + +Put the RGB values of your colors into `normal.pal` between the first and the last color and the RGB values for the shiny version into `shiny.pal`. +Edit `footprint.png` using two colors in indexed mode, black and white. +Finally, edit `icon.png`. +**Note**: the icon will use one of 6 predefined palettes instead of `normal.pal`. +Open an icon sprite and load one of the palettes to find out which palette suits your icon sprite best. + +## 2. Add the sprites to the rom +Sadly, just putting the image files into the graphics folder is not enough. To use the sprites we have to register them, which is kind of tedious. +First, create constants for the file paths. You'll want to add the constants for your species after the constants for the last valid species. + +Edit [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/graphics/pokemon.h): + +```diff +#if P_FAMILY_PECHARUNT + const u32 gMonFrontPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/front.4bpp.lz"); + const u32 gMonPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/normal.gbapal.lz"); + const u32 gMonBackPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/back.4bpp.lz"); + const u32 gMonShinyPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/shiny.gbapal.lz"); + const u8 gMonIcon_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/icon.4bpp"); +#if P_FOOTPRINTS + const u8 gMonFootprint_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/footprint.1bpp"); +#endif //P_FOOTPRINTS +#if OW_POKEMON_OBJECT_EVENTS + const u32 gObjectEventPic_Pecharunt[] = INCBIN_COMP("graphics/pokemon/pecharunt/overworld.4bpp"); +#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE + const u32 gOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_normal.gbapal.lz"); + const u32 gShinyOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_shiny.gbapal.lz"); +#endif //OW_PKMN_OBJECTS_SHARE_PALETTES +#endif //OW_POKEMON_OBJECT_EVENTS +#endif //P_FAMILY_PECHARUNT + + const u32 gMonFrontPic_Egg[] = INCBIN_U32("graphics/pokemon/egg/anim_front.4bpp.lz"); + const u32 gMonPalette_Egg[] = INCBIN_U32("graphics/pokemon/egg/normal.gbapal.lz"); + const u8 gMonIcon_Egg[] = INCBIN_U8("graphics/pokemon/egg/icon.4bpp"); + ++ const u32 gMonFrontPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/anim_front.4bpp.lz"); ++ const u32 gMonBackPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/back.4bpp.lz"); ++ const u32 gMonPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/normal.gbapal.lz"); ++ const u32 gMonShinyPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/shiny.gbapal.lz"); ++ const u8 gMonIcon_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/icon.4bpp"); ++ const u8 gMonFootprint_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/footprint.1bpp"); +``` + +Please note that Pecharunt, the Pokémon that should be above your insertion for the time being, reads a `front.png` sprite instead of an `anim_front.png` sprite. This is because currently, Pecharunt lacks a 2nd frame. If the front sprite sheet of your species uses 2 frames, you should use `anim_front`. + +## 3. Add the animations to the rom + +You can define the animation order, in which the sprites will be shown. The first number is the sprite index (so 0 or 1) and the second number is the number of frames the sprite will be visible. + +Edit [src/data/pokemon_graphics/front_pic_anims.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon_graphics/front_pic_anims.h): + +```diff +#if P_FAMILY_PECHARUNT +PLACEHOLDER_ANIM_SINGLE_FRAME(Pecharunt); +#endif //P_FAMILY_PECHARUNT + ++static const union AnimCmd sAnim_Mewthree_1[] = ++{ ++ ANIMCMD_FRAME(1, 30), ++ ANIMCMD_FRAME(0, 20), ++ ANIMCMD_END, ++}; +``` + +```diff +#if P_FAMILY_PECHARUNT +SINGLE_ANIMATION(Pecharunt); +#endif //P_FAMILY_PECHARUNT ++SINGLE_ANIMATION(Mewthree); +SINGLE_ANIMATION(Egg); +``` + +You might be wondering what `PLACEHOLDER_ANIM_SINGLE_FRAME` is. Well, since Pecharun only has 1 frame, we use what's called a preprocessor *macro* to have in a single line what otherwise would've been this in the C file: +```c +static const union AnimCmd sAnim_Pecharunt_1[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END, +} +``` +Instead, we can use the already established macro that does the same thing, replacing the value in parenthesis with what we want (in this case, `Pecharunt`): +```c +#define PLACEHOLDER_ANIM_SINGLE_FRAME(name) \ +static const union AnimCmd sAnim_##name##_1[] = \ +{ \ + ANIMCMD_FRAME(0, 1), \ + ANIMCMD_END, \ +} +``` + +## 4. Linking graphic information to our Pokémon +Now that we have all the external data ready, we just need to add it to `gSpeciesInfo` plus the rest of the animation and graphical data that we want to use: + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .pokemonScale = 256, + .pokemonOffset = 0, + .trainerScale = 290, + .trainerOffset = 2, ++ .frontPic = gMonFrontPic_Mewthree, ++ .frontPicSize = MON_COORDS_SIZE(64, 64), ++ .frontPicYOffset = 0, ++ .frontAnimFrames = sAnims_Mewthree, ++ .frontAnimId = ANIM_GROW_VIBRATE, ++ .frontAnimDelay = 15, ++ .enemyMonElevation = 6, ++ .backPic = gMonBackPic_Mewthree, ++ .backPicSize = MON_COORDS_SIZE(64, 64), ++ .backPicYOffset = 0, ++ .backAnimId = BACK_ANIM_CONCAVE_ARC_SMALL, ++ .palette = gMonPalette_Mewthree, ++ .shinyPalette = gMonShinyPalette_Mewthree, + .iconSprite = gMonIcon_Mewthree, + .iconPalIndex = 2, ++ FOOTPRINT(Mewthree) + }, + }; +``` +Let's explain each of these: +- `frontPic`: + - Used to reference the front sprite, so in this case, we call for `gMonFrontPic_Mewthree`. +- `frontPicSize`: + - The two values (`width` and `height`) are used for defining the non-empty size of the front sprite, which is used in move animations. If you're unsure of the values, you can leave them both as 64. +- `frontPicYOffset`: + - Used to define what Y position the sprite sits at. This is used to set where they'd be "grounded". For the shadow, see `enemyMonElevation`. +- `frontAnimFrames`: + - We link our animation frame animations that we defined earlier here. +- `frontAnimId`: + - Because you are limited to two frames, there are already [predefined front sprite animations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/pokemon_animation.h), describing translations, rotations, scalings or color changes. +- `frontAnimDelay`: + - Sets a delay in frame count between when the Pokémon appears and when the animation starts. +- `enemyMonElevation`: + - Used to determine the altitude from the ground. Any value above 0 will show a shadow under the Pokémon, to signify that they're floating. +- `backPic`: + - Used to reference the back sprite, so in this case, we call for `gMonBackPic_Mewthree`. +- `backPicSize`: + - The two values (`width` and `height`) are used for defining the non-empty size of the back sprite, which is used in move animations. If you're unsure of the values, you can leave them both as 64. + - **NOTE**: Mew has a tarnary switch here in order to change values depending on if a config option is set for displaying th original Gen 3 sprites. +- `backPicYOffset`: + - Used to define what Y position of the back sprite. When working with the animation debug menu, we recommend aligning the back sprite to the white background, as it was designed to properyly align with the real battle layout. +- `backAnimId`: + - Like `frontAnimId` except for the back sprites and them being a single frame. The IDs listed [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/pokemon_animation.h) are used to represent 3 different animations that happen based on the the Pokémon's nature. +- `palette`: + - Used to reference the non-shiny palette, so in this case, we call for `gMonPalette_Mewthree`. +- `shinyPalette`: + - Used to reference the shiny palette, so in this case, we call for `gMonShinyPalette_Mewthree`. +- `iconSprite`: + - Used to reference the icon sprite, so in this case, we call for `gMonIcon_Mewthree`. +- `iconPalIndex`: + - Here, you can choose between the six icon palettes; 0, 1, 2, 3, 4 and 5. All of them located in `graphics/pokemon/icon_palettes`. +- `FOOTPRINT` + - We made this single field into a macro so that they can be ignored when `P_FOOTPRINTS` is set to false. It's also why we don't have an "," after calling it like the other macros (we add it as part of the macro itself). + ```c + #if P_FOOTPRINTS + #define FOOTPRINT(sprite) .footprint = gMonFootprint_## sprite, + #else + #define FOOTPRINT(sprite) + #endif + ``` + +# The Data - Part 2 + +We're almost there just a bit left! + +## 1. Species Flags + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE }, + .bodyColor = BODY_COLOR_PURPLE, ++ .isLegendary = TRUE, ++ .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, + }, + }; +``` +Each species flag provides properties to the species: +- `isLegendary`: + - Does nothing. +- `isMythical`: + - Is skipped during Pokédex evaluations. + - Unless it also has the `dexForceRequired` flag. + - Cannot obtain Gigantamax factor via `ToggleGigantamaxFactor`. +- `isUltraBeast`: + - Beast Ball's multiplier is set to x5 for this species. + - All other ball multipliers are set to x0.1. +- `isParadox` (previously `isParadoxForm`): + - Makes it so that Booster Energy cannot be knocked off. +- `isTotem`: + - Does nothing. +- `isMegaEvolution`: + - A Mega indicator is added to the battle box indicating that they're Mega Evolved. + - The species doesn't receive affection benefits. + - Required when adding new Mega Evolutions. +- `isPrimalReversion`: + - A Primal Reversion indicator (Alpha or Omega for Kyogre/Groudon respectively) is added to the battle box indicating that they're Primal Reverted. + - Required when adding new Primal Reversions. +- `isUltraBurst`: + - Required when adding new Ultra Burst forms. +- `isGigantamax`: + - Used to determine if Gigantamax forms should have their GMax moves or not. + - Required when adding new Gigantamax forms. +- `isAlolanForm`, `isGalarianForm`, `isHisuianForm`, `isPaldeanForm`: + - In the future, these will be used to determine breeding offspring from different based on their region. +- `cannotBeTraded`: + - This species cannot be traded away (like Black/White Kyurem). +- `perfectIVCount`: + - Guarantees that the number of IVs specified here will be perfect. +- `tmIlliterate`: + - This species will be unable to learn the universal moves. +- `isFrontierBanned`: + - This species will be unable to enter Battle Frontier facilities. Replaces `gFrontierBannedSpecies`. + +## 2. Delimit the moveset + +Let's begin with the moves that can be learned by leveling up. + +Append to [src/data/pokemon/level_up_learnsets/gen_9.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/level_up_learnsets/gen_9.h): +**NOTE**: You can ignore the warning at the top of the file if you're just adding moves to Pokemon. + +```diff +#if P_FAMILY_PECHARUNT +static const struct LevelUpMove sPecharuntLevelUpLearnset[] = { + LEVEL_UP_MOVE( 1, MOVE_SMOG), + LEVEL_UP_MOVE( 1, MOVE_POISON_GAS), + LEVEL_UP_MOVE( 1, MOVE_MEMENTO), + LEVEL_UP_MOVE( 1, MOVE_ASTONISH), + LEVEL_UP_MOVE( 8, MOVE_WITHDRAW), + LEVEL_UP_MOVE(16, MOVE_DESTINY_BOND), + LEVEL_UP_MOVE(24, MOVE_FAKE_TEARS), + LEVEL_UP_MOVE(32, MOVE_PARTING_SHOT), + LEVEL_UP_MOVE(40, MOVE_SHADOW_BALL), + LEVEL_UP_MOVE(48, MOVE_MALIGNANT_CHAIN), + LEVEL_UP_MOVE(56, MOVE_TOXIC), + LEVEL_UP_MOVE(64, MOVE_NASTY_PLOT), + LEVEL_UP_MOVE(72, MOVE_RECOVER), + LEVEL_UP_END +}; +#endif + ++static const struct LevelUpMove sMewthreeLevelUpLearnset[] = { ++ LEVEL_UP_MOVE( 1, MOVE_CONFUSION), ++ LEVEL_UP_MOVE( 1, MOVE_DISABLE), ++ LEVEL_UP_MOVE(11, MOVE_BARRIER), ++ LEVEL_UP_MOVE(22, MOVE_SWIFT), ++ LEVEL_UP_MOVE(33, MOVE_PSYCH_UP), ++ LEVEL_UP_MOVE(44, MOVE_FUTURE_SIGHT), ++ LEVEL_UP_MOVE(55, MOVE_MIST), ++ LEVEL_UP_MOVE(66, MOVE_PSYCHIC), ++ LEVEL_UP_MOVE(77, MOVE_AMNESIA), ++ LEVEL_UP_MOVE(88, MOVE_RECOVER), ++ LEVEL_UP_MOVE(99, MOVE_SAFEGUARD), ++ LEVEL_UP_END ++}; +``` +**NOTE**: If `P_LVL_UP_LEARNSETS` is not set to something equal to `GEN_9`, the file to be edited will change to what's specified. + +Again, we need to register the learnset in `gSpeciesInfo`: + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + .palette = gMonPalette_Mewthree, + .shinyPalette = gMonShinyPalette_Mewthree, + .iconSprite = gMonIcon_Mewthree, + .iconPalIndex = 2, ++ .levelUpLearnset = sMewthreeLevelUpLearnset, + }, + }; +``` + +Next we need to specify which moves can be taught via TM, HM, or Move Tutor. + +Append to [src/data/pokemon/teachable_learnsets.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/teachable_learnsets.h): + +```diff +#if P_FAMILY_PECHARUNT +static const u16 sPecharuntTeachableLearnset[] = { + ... + MOVE_UNAVAILABLE, +}; +#endif //P_FAMILY_PECHARUNT + ++static const u16 sMewthreeTeachableLearnset[] = { ++ MOVE_FOCUS_PUNCH, ++ MOVE_WATER_PULSE, ++ MOVE_CALM_MIND, ++ MOVE_TOXIC, ++ MOVE_HAIL, ++ MOVE_BULK_UP, ++ MOVE_HIDDEN_POWER, ++ MOVE_SUNNY_DAY, ++ MOVE_TAUNT, ++ MOVE_ICE_BEAM, ++ MOVE_BLIZZARD, ++ MOVE_HYPER_BEAM, ++ MOVE_LIGHT_SCREEN, ++ MOVE_PROTECT, ++ MOVE_RAIN_DANCE, ++ MOVE_SAFEGUARD, ++ MOVE_FRUSTRATION, ++ MOVE_SOLAR_BEAM, ++ MOVE_IRON_TAIL, ++ MOVE_THUNDERBOLT, ++ MOVE_THUNDER, ++ MOVE_EARTHQUAKE, ++ MOVE_RETURN, ++ MOVE_PSYCHIC, ++ MOVE_SHADOW_BALL, ++ MOVE_BRICK_BREAK, ++ MOVE_DOUBLE_TEAM, ++ MOVE_REFLECT, ++ MOVE_SHOCK_WAVE, ++ MOVE_FLAMETHROWER, ++ MOVE_SANDSTORM, ++ MOVE_FIRE_BLAST, ++ MOVE_ROCK_TOMB, ++ MOVE_AERIAL_ACE, ++ MOVE_TORMENT, ++ MOVE_FACADE, ++ MOVE_SECRET_POWER, ++ MOVE_REST, ++ MOVE_SKILL_SWAP, ++ MOVE_SNATCH, ++ MOVE_STRENGTH, ++ MOVE_FLASH, ++ MOVE_ROCK_SMASH, ++ MOVE_MEGA_PUNCH, ++ MOVE_MEGA_KICK, ++ MOVE_BODY_SLAM, ++ MOVE_DOUBLE_EDGE, ++ MOVE_COUNTER, ++ MOVE_SEISMIC_TOSS, ++ MOVE_MIMIC, ++ MOVE_METRONOME, ++ MOVE_DREAM_EATER, ++ MOVE_THUNDER_WAVE, ++ MOVE_SUBSTITUTE, ++ MOVE_DYNAMIC_PUNCH, ++ MOVE_PSYCH_UP, ++ MOVE_SNORE, ++ MOVE_ICY_WIND, ++ MOVE_ENDURE, ++ MOVE_MUD_SLAP, ++ MOVE_ICE_PUNCH, ++ MOVE_SWAGGER, ++ MOVE_SLEEP_TALK, ++ MOVE_SWIFT, ++ MOVE_THUNDER_PUNCH, ++ MOVE_FIRE_PUNCH, ++ MOVE_UNAVAILABLE, // This is required to determine where the array ends. ++}; +#endif +``` + +Once more, we need to register the learnset in `gSpeciesInfo`: + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + FOOTPRINT(Mewthree) + .levelUpLearnset = sMewthreeLevelUpLearnset, ++ .teachableLearnset = sMewthreeTeachableLearnset, + }, + }; +``` + +If you want to create a Pokémon which can breed, you will need to edit [src/data/pokemon/egg_moves.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/egg_moves.h). + + +## 3. Define the Evolutions + +We want Mewthree to evolve from Mewtwo by reaching level 100. + +Edit `gSpeciesInfo`: + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTWO] = + { + ... + FOOTPRINT(Mewtwo) + .isLegendary = TRUE, + .levelUpLearnset = sMewtwoLevelUpLearnset, + .teachableLearnset = sMewtwoTeachableLearnset, + .formSpeciesIdTable = sMewtwoFormSpeciesIdTable, + .formChangeTable = sMewtwoFormChangeTable, ++ .evolutions = EVOLUTION({EVO_LEVEL, 100, SPECIES_MEWTHREE}), + }, + }; +``` + +## 4. Make it appear! +Now Mewthree really does slumber in the games code - but we won't know until we make him appear somewhere! The legend tells that Mewthree is hiding somewhere in Petalburg Woods... + +Edit [src/data/wild_encounters.json](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/wild_encounters.json): + +```diff + { + "map": "MAP_PETALBURG_WOODS", + "base_label": "gPetalburgWoods", + "land_mons": { + "encounter_rate": 20, + "mons": [ + { + "min_level": 5, + "max_level": 5, + "species": "SPECIES_POOCHYENA" + }, + { + "min_level": 5, + "max_level": 5, + "species": "SPECIES_WURMPLE" + }, + { + "min_level": 5, + "max_level": 5, + "species": "SPECIES_SHROOMISH" + }, + { +- "min_level": 6, +- "max_level": 6, +- "species": "SPECIES_POOCHYENA" ++ "min_level": 5, ++ "max_level": 5, ++ "species": "SPECIES_MEWTHREE" + }, + ... + } +``` + +Congratulations, you have created your own personal pocket monster! You may call yourself a mad scientist now. + +# Optional data + +Now that you now have all the essential pieces to create a base species, there are some aspects that you might want to know if you want to do other stuff with your custom Pokémon. + +## 1. Form tables +Found in `src/data/pokemon/form_species_tables.h`. + +These are introduced to have a reference of what forms correspond to what Species of Pokémon. For example, we have Pikachu's table: +```c +#if P_FAMILY_PIKACHU +static const u16 sPikachuFormSpeciesIdTable[] = { + SPECIES_PIKACHU, + SPECIES_PIKACHU_COSPLAY, + SPECIES_PIKACHU_ROCK_STAR, + SPECIES_PIKACHU_BELLE, + SPECIES_PIKACHU_POP_STAR, + SPECIES_PIKACHU_PH_D, + SPECIES_PIKACHU_LIBRE, + SPECIES_PIKACHU_ORIGINAL_CAP, + SPECIES_PIKACHU_HOENN_CAP, + SPECIES_PIKACHU_SINNOH_CAP, + SPECIES_PIKACHU_UNOVA_CAP, + SPECIES_PIKACHU_KALOS_CAP, + SPECIES_PIKACHU_ALOLA_CAP, + SPECIES_PIKACHU_PARTNER_CAP, + SPECIES_PIKACHU_WORLD_CAP, + FORM_SPECIES_END, +}; +#endif //P_FAMILY_PIKACHU +``` +We register the table each form entry in `gSpeciesInfo`. + +```diff + [SPECIES_PIKACHU] = + { + ... + .teachableLearnset = sPikachuTeachableLearnset, ++ .formSpeciesIdTable = sPikachuFormSpeciesIdTable, + .evolutions = EVOLUTION({EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_RAICHU}, + {EVO_NONE, 0, SPECIES_RAICHU_ALOLAN}), + }, + + [SPECIES_PIKACHU_COSPLAY] = + { + ... + .teachableLearnset = sPikachuTeachableLearnset, ++ .formSpeciesIdTable = sPikachuFormSpeciesIdTable, + }, +``` +...and so on. + +What this allows us to do is to be able to get all forms of a Pokémon in our code by using the `GetSpeciesFormTable` function. + +For example, in the HGSS dex, it lets us browse between the entries of every form available.: + +![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/a1a90b79-46a1-4cd6-97d6-ec5d741bfdc8) ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/7cffc6be-0b5c-4074-b689-736a97297843) + +In addition, we have the `GET_BASE_SPECIES_ID` macro, which returns the first entry of the table (or return the species itself if it doesn't have a table registered). With this, you can check if a Pokémon is any form of a species. For example, making it so that the Light Ball affects all Pikachu forms: +```c + case HOLD_EFFECT_LIGHT_BALL: + if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_PIKACHU && IS_MOVE_SPECIAL(move)) + modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); + break; +``` + +## 2. Form change tables +Found in `src/data/pokemon/form_species_tables.h`. + +These tables, unlike the regular form tables, registers how Pokémon can switch between forms. + +```c +#if P_FAMILY_GASTLY +static const struct FormChange sGengarFormChangeTable[] = { + {FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GENGAR_MEGA, ITEM_GENGARITE}, + {FORM_CHANGE_BATTLE_GIGANTAMAX, SPECIES_GENGAR_GIGANTAMAX}, + {FORM_CHANGE_TERMINATOR}, +}; +#endif //P_FAMILY_GASTLY +``` +The first value is the type of form change. In the case of Gengar, we have both Mega Evolution and Gigantamax form changes. + +The second value is the target form, to which the Pokémon will change into. + +Values after that are referred as arguments, and needs to be put there depends on the type of form change, detailed in `include/constants/form_change_types.h`. + +## 3. Gender differences +![mGBA_Wq5cbDkNZG](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/45256192-b451-4baa-af06-f57ca16e1e46) + +You may have seen that there's a couple of duplicate fields with a "Female" suffix. +```diff + [SPECIES_FRILLISH] = + { + ... + .frontPic = gMonFrontPic_Frillish, ++ .frontPicFemale = gMonFrontPic_FrillishF, + .frontPicSize = MON_COORDS_SIZE(56, 56), ++ .frontPicSizeFemale = MON_COORDS_SIZE(56, 56), + .frontPicYOffset = 5, + .frontAnimFrames = sAnims_Frillish, + .frontAnimId = ANIM_RISING_WOBBLE, + .backPic = gMonBackPic_Frillish, ++ .backPicFemale = gMonBackPic_FrillishF, + .backPicSize = MON_COORDS_SIZE(40, 56), ++ .backPicSizeFemale = MON_COORDS_SIZE(40, 56), + .backPicYOffset = 7, + .backAnimId = BACK_ANIM_CONVEX_DOUBLE_ARC, + .palette = gMonPalette_Frillish, ++ .paletteFemale = gMonPalette_FrillishF, + .shinyPalette = gMonShinyPalette_Frillish, ++ .shinyPaletteFemale = gMonShinyPalette_FrillishF, + .iconSprite = gMonIcon_Frillish, ++ .iconSpriteFemale = gMonIcon_FrillishF, + .iconPalIndex = 0, ++ .iconPalIndexFemale = 1, + FOOTPRINT(Frillish) + .levelUpLearnset = sFrillishLevelUpLearnset, + .teachableLearnset = sFrillishTeachableLearnset, + .evolutions = EVOLUTION({EVO_LEVEL, 40, SPECIES_JELLICENT}), + }, +``` +These are used to change the graphics of the Pokémon if they're female. If they're not registered, they default to the male values. + +However, `iconPalIndexFemale` is a special case, where it's *doesn't* read the male icon palette if its `iconSpriteFemale` is set, so if you're setting a female icon, be sure to set their palette index as well. + +## 4. Overworld Data +![mGBA_4iqvhhSltK](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/e59238dc-9779-4f26-a9e7-159a32caa3d9) + +If you have `OW_POKEMON_OBJECT_EVENTS` in your hack, you can add Overworld of your new species by following these steps: + +First, since you copied the contents from Mew's folder previously, you should also have copied its overworld sprites. Edit those to your liking, as we have done before, making sure to update the palettes + +Secondly, in [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/graphics/pokemon.h), add the following: + +```diff + const u8 gMonIcon_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/icon.4bpp"); + const u8 gMonFootprint_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/footprint.1bpp"); ++ const u32 gObjectEventPic_Mewthree[] = INCBIN_COMP("graphics/pokemon/mewthree/overworld.4bpp"); ++ const u32 gOverworldPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/overworld_normal.gbapal.lz"); ++ const u32 gShinyOverworldPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/overworld_shiny.gbapal.lz"); +``` + +Thirdly, in [spritesheet_rules.mk](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/spritesheet_rules.mk) + +```diff +$(POKEMONGFXDIR)/mewtwo/overworld.4bpp: %.4bpp: %.png + $(GFX) $< $@ -mwidth 4 -mheight 4 + ++$(POKEMONGFXDIR)/mewthree/overworld.4bpp: %.4bpp: %.png ++ $(GFX) $< $@ -mwidth 4 -mheight 4 + +$(POKEMONGFXDIR)/mew/overworld.4bpp: %.4bpp: %.png + $(GFX) $< $@ -mwidth 4 -mheight 4 +``` + +Fourthly, in [src/data/object_events/object_event_pic_tables_followers.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/object_events/object_event_pic_tables_followers.h): +```diff +#if P_FAMILY_PECHARUNT +/*static const struct SpriteFrameImage sPicTable_Pecharunt[] = { + overworld_ascending_frames(gObjectEventPic_Pecharunt, 4, 4), +};*/ +#endif //P_FAMILY_PECHARUNT + ++static const struct SpriteFrameImage sPicTable_Mewthree[] = { ++ overworld_ascending_frames(gObjectEventPic_Mewthree, 4, 4), ++}; +``` + +And finally, in `gSpeciesInfo`: + +```diff + const struct SpeciesInfo gSpeciesInfo[] = + { + ... + [SPECIES_MEWTHREE] = + { + ... + FOOTPRINT(Mewthree) ++ OVERWORLD( ++ sPicTable_Mewthree, ++ SIZE_32x32, ++ SHADOW_SIZE_M, ++ TRACKS_FOOT, ++ gOverworldPalette_Mewthree, ++ gShinyOverworldPalette_Mewthree ++ ) + .levelUpLearnset = sMewthreeLevelUpLearnset, + .teachableLearnset = sMewthreeTeachableLearnset, + }, + }; +``` + +### Sprite Size +Depending on your species, you might want to use different sizes for it. For example, certain species known for being big like Steelix use sprites that fit a 64x64 frame instead of 32x32, and as such have `SIZE_64x64` in their data instead of `SIZE_32x32` to accomodate for them. + +Also, in `spritesheet_rules.mk`, `-mwidth` and `-mheight` need to be set to 8 instead of 4 for such cases. + +### Shadows +Gen 4 style shadows are defined by the `SHADOW` macro which takes the following arguments: + - X offset + - Y offset + - Shadow size +You have 4 options for their shadow, between Small, Medium, Large and Extra Large: + - `SHADOW_SIZE_S` + - `SHADOW_SIZE_M` + - `SHADOW_SIZE_L` + - `SHADOW_SIZE_XL_BATTLE_ONLY` +To make the Pokémon have no shadow, use the `NO_SHADOW` macro instead of `SHADOW`. + +### Tracks +You have 4 options for the tracks that your species will leave behind on sand. + - `TRACKS_NONE` + - `TRACKS_FOOT` ![sand_footprints](https://github.com/user-attachments/assets/8b8c34d6-72e9-4b9d-839d-0a5cc1ae1a4c) + - `TRACKS_SLITHER` ![slither_tracks](https://github.com/user-attachments/assets/28219c05-61e0-48b3-9aeb-43f48e4ffdd4) + - `TRACKS_SPOT` ![spot_tracks](https://github.com/user-attachments/assets/f7a24887-c5ca-47f2-8825-01f3df61deca) + - `TRACKS_BUG` ![bug_tracks](https://github.com/user-attachments/assets/8cd1dea4-4123-4af8-a558-992874a6d589) + + ...though technically you can also use `TRACKS_BIKE_TIRE` if you wish to. + +![bike_tire_tracks](https://github.com/user-attachments/assets/ac81d211-85e5-443a-ac54-c2976f1f0b82) diff --git a/graphics/pokemon/araquanid/icon.png b/graphics/pokemon/araquanid/icon.png index fa13eba83329..10676126a1f0 100644 Binary files a/graphics/pokemon/araquanid/icon.png and b/graphics/pokemon/araquanid/icon.png differ diff --git a/graphics/pokemon/audino/overworld.png b/graphics/pokemon/audino/overworld.png index 27fdc5f6b764..082abdd27060 100644 Binary files a/graphics/pokemon/audino/overworld.png and b/graphics/pokemon/audino/overworld.png differ diff --git a/graphics/pokemon/bewear/icon.png b/graphics/pokemon/bewear/icon.png index 5ceb073fbcfb..30cc96672326 100644 Binary files a/graphics/pokemon/bewear/icon.png and b/graphics/pokemon/bewear/icon.png differ diff --git a/graphics/pokemon/blacephalon/icon.png b/graphics/pokemon/blacephalon/icon.png index bb1f9cdc31f5..c3fad2f3efe4 100644 Binary files a/graphics/pokemon/blacephalon/icon.png and b/graphics/pokemon/blacephalon/icon.png differ diff --git a/graphics/pokemon/boldore/overworld.png b/graphics/pokemon/boldore/overworld.png index 013a09dcf3d4..e4c4cb5b11e2 100644 Binary files a/graphics/pokemon/boldore/overworld.png and b/graphics/pokemon/boldore/overworld.png differ diff --git a/graphics/pokemon/bounsweet/icon.png b/graphics/pokemon/bounsweet/icon.png index 80df38b9ad58..5fa805deb0e9 100644 Binary files a/graphics/pokemon/bounsweet/icon.png and b/graphics/pokemon/bounsweet/icon.png differ diff --git a/graphics/pokemon/brionne/icon.png b/graphics/pokemon/brionne/icon.png index da33e8ee0715..88cf5d01b40f 100644 Binary files a/graphics/pokemon/brionne/icon.png and b/graphics/pokemon/brionne/icon.png differ diff --git a/graphics/pokemon/bruxish/icon.png b/graphics/pokemon/bruxish/icon.png index 00d049a5c6f8..eab625140ebb 100644 Binary files a/graphics/pokemon/bruxish/icon.png and b/graphics/pokemon/bruxish/icon.png differ diff --git a/graphics/pokemon/bulbasaur/icon.png b/graphics/pokemon/bulbasaur/icon.png index 7738836b9ca7..d8f508ee8688 100644 Binary files a/graphics/pokemon/bulbasaur/icon.png and b/graphics/pokemon/bulbasaur/icon.png differ diff --git a/graphics/pokemon/buzzwole/icon.png b/graphics/pokemon/buzzwole/icon.png index 72e3270dac92..c1126c081d05 100644 Binary files a/graphics/pokemon/buzzwole/icon.png and b/graphics/pokemon/buzzwole/icon.png differ diff --git a/graphics/pokemon/celesteela/icon.png b/graphics/pokemon/celesteela/icon.png index 854c36851a93..7722e43dacc0 100644 Binary files a/graphics/pokemon/celesteela/icon.png and b/graphics/pokemon/celesteela/icon.png differ diff --git a/graphics/pokemon/charjabug/icon.png b/graphics/pokemon/charjabug/icon.png index eb2f9206e9b0..6743ab681812 100644 Binary files a/graphics/pokemon/charjabug/icon.png and b/graphics/pokemon/charjabug/icon.png differ diff --git a/graphics/pokemon/cinderace/gmax/icon.png b/graphics/pokemon/cinderace/gmax/icon.png index 3d1f1e423751..791801bb65e6 100644 Binary files a/graphics/pokemon/cinderace/gmax/icon.png and b/graphics/pokemon/cinderace/gmax/icon.png differ diff --git a/graphics/pokemon/comfey/icon.png b/graphics/pokemon/comfey/icon.png index 916ac5c188d1..10d1a3fe5aa1 100644 Binary files a/graphics/pokemon/comfey/icon.png and b/graphics/pokemon/comfey/icon.png differ diff --git a/graphics/pokemon/cosmoem/icon.png b/graphics/pokemon/cosmoem/icon.png index ab4c13b8f260..c461bdadaf47 100644 Binary files a/graphics/pokemon/cosmoem/icon.png and b/graphics/pokemon/cosmoem/icon.png differ diff --git a/graphics/pokemon/cosmog/icon.png b/graphics/pokemon/cosmog/icon.png index 6057034a9a87..a74b399d12c0 100644 Binary files a/graphics/pokemon/cosmog/icon.png and b/graphics/pokemon/cosmog/icon.png differ diff --git a/graphics/pokemon/cottonee/overworld.png b/graphics/pokemon/cottonee/overworld.png index 15aec0406727..55a0d48bad51 100644 Binary files a/graphics/pokemon/cottonee/overworld.png and b/graphics/pokemon/cottonee/overworld.png differ diff --git a/graphics/pokemon/cottonee/overworld_normal.pal b/graphics/pokemon/cottonee/overworld_normal.pal index 76222db0ce6b..2af87bcf9fe7 100644 --- a/graphics/pokemon/cottonee/overworld_normal.pal +++ b/graphics/pokemon/cottonee/overworld_normal.pal @@ -3,17 +3,17 @@ JASC-PAL 16 152 208 160 110 110 110 -204 227 209 -208 241 229 -164 207 173 +198 212 159 +222 230 197 +165 173 132 64 128 16 92 224 48 74 176 49 47 46 47 -198 196 235 -137 162 175 +165 173 132 +123 132 107 238 238 247 137 117 107 -230 77 40 +230 132 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/cottonee/overworld_shiny.pal b/graphics/pokemon/cottonee/overworld_shiny.pal index bb3d8c85c8f3..d530eb089465 100644 --- a/graphics/pokemon/cottonee/overworld_shiny.pal +++ b/graphics/pokemon/cottonee/overworld_shiny.pal @@ -11,9 +11,9 @@ JASC-PAL 192 96 40 47 46 47 192 176 136 -137 162 175 +112 96 40 248 248 248 -137 117 107 -230 77 40 +138 106 91 +112 184 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/crabominable/icon.png b/graphics/pokemon/crabominable/icon.png index e3f32d50465c..c3ae3235b67d 100644 Binary files a/graphics/pokemon/crabominable/icon.png and b/graphics/pokemon/crabominable/icon.png differ diff --git a/graphics/pokemon/crabrawler/icon.png b/graphics/pokemon/crabrawler/icon.png index d28b81b6b6b5..47b3b3451248 100644 Binary files a/graphics/pokemon/crabrawler/icon.png and b/graphics/pokemon/crabrawler/icon.png differ diff --git a/graphics/pokemon/cutiefly/icon.png b/graphics/pokemon/cutiefly/icon.png index 5e25a942da95..25af39c74ccf 100644 Binary files a/graphics/pokemon/cutiefly/icon.png and b/graphics/pokemon/cutiefly/icon.png differ diff --git a/graphics/pokemon/dartrix/icon.png b/graphics/pokemon/dartrix/icon.png index 39fb8fddd094..bd378938d322 100644 Binary files a/graphics/pokemon/dartrix/icon.png and b/graphics/pokemon/dartrix/icon.png differ diff --git a/graphics/pokemon/decidueye/icon.png b/graphics/pokemon/decidueye/icon.png index 6078f20b83ed..8cb628c31f04 100644 Binary files a/graphics/pokemon/decidueye/icon.png and b/graphics/pokemon/decidueye/icon.png differ diff --git a/graphics/pokemon/deoxys/anim_front.png b/graphics/pokemon/deoxys/anim_front.png index d2f3e9938189..fc782931d158 100644 Binary files a/graphics/pokemon/deoxys/anim_front.png and b/graphics/pokemon/deoxys/anim_front.png differ diff --git a/graphics/pokemon/deoxys/attack/anim_front.png b/graphics/pokemon/deoxys/attack/anim_front.png index 0b43a9fe11e1..566e80eafd01 100644 Binary files a/graphics/pokemon/deoxys/attack/anim_front.png and b/graphics/pokemon/deoxys/attack/anim_front.png differ diff --git a/graphics/pokemon/deoxys/attack/normal.pal b/graphics/pokemon/deoxys/attack/normal.pal index 246d4784a280..52ddbb8fc666 100644 --- a/graphics/pokemon/deoxys/attack/normal.pal +++ b/graphics/pokemon/deoxys/attack/normal.pal @@ -3,8 +3,8 @@ JASC-PAL 16 248 160 176 96 56 56 -248 112 72 -184 104 104 +255 115 74 +204 65 65 24 24 24 104 200 224 80 144 176 diff --git a/graphics/pokemon/deoxys/defense/anim_front.png b/graphics/pokemon/deoxys/defense/anim_front.png index 2ee6e0c527ed..ce3cdad39cf4 100644 Binary files a/graphics/pokemon/deoxys/defense/anim_front.png and b/graphics/pokemon/deoxys/defense/anim_front.png differ diff --git a/graphics/pokemon/deoxys/defense/normal.pal b/graphics/pokemon/deoxys/defense/normal.pal index 8b37f5111e5f..4beda8613669 100644 --- a/graphics/pokemon/deoxys/defense/normal.pal +++ b/graphics/pokemon/deoxys/defense/normal.pal @@ -3,9 +3,9 @@ JASC-PAL 16 248 160 176 96 56 56 -192 104 104 -248 112 72 -96 64 48 +204 65 65 +255 115 74 +68 28 89 240 176 144 104 200 224 80 144 176 diff --git a/graphics/pokemon/deoxys/defense/shiny.pal b/graphics/pokemon/deoxys/defense/shiny.pal index c1f34410a4a8..3f285246c61f 100644 --- a/graphics/pokemon/deoxys/defense/shiny.pal +++ b/graphics/pokemon/deoxys/defense/shiny.pal @@ -5,7 +5,7 @@ JASC-PAL 112 96 16 168 168 56 248 232 64 -96 64 48 +49 29 82 248 248 216 112 208 168 72 160 112 diff --git a/graphics/pokemon/deoxys/normal.pal b/graphics/pokemon/deoxys/normal.pal index 59124c56a955..e11c27771985 100644 --- a/graphics/pokemon/deoxys/normal.pal +++ b/graphics/pokemon/deoxys/normal.pal @@ -2,12 +2,12 @@ JASC-PAL 0100 16 248 160 176 -184 104 104 +204 65 65 248 176 144 -248 112 72 +255 115 74 96 56 56 104 200 224 -88 56 48 +68 28 89 56 80 96 80 144 176 152 96 176 diff --git a/graphics/pokemon/deoxys/shiny.pal b/graphics/pokemon/deoxys/shiny.pal index 5bbc6b683ac0..621aac6d4285 100644 --- a/graphics/pokemon/deoxys/shiny.pal +++ b/graphics/pokemon/deoxys/shiny.pal @@ -7,7 +7,7 @@ JASC-PAL 248 232 64 112 96 16 112 208 168 -112 96 16 +51 27 101 56 96 88 72 160 112 96 120 192 diff --git a/graphics/pokemon/deoxys/speed/anim_front.png b/graphics/pokemon/deoxys/speed/anim_front.png index 947052f81d3a..1f2063bddf7c 100644 Binary files a/graphics/pokemon/deoxys/speed/anim_front.png and b/graphics/pokemon/deoxys/speed/anim_front.png differ diff --git a/graphics/pokemon/deoxys/speed/normal.pal b/graphics/pokemon/deoxys/speed/normal.pal index dad052e1daf5..ea1073a0ee35 100644 --- a/graphics/pokemon/deoxys/speed/normal.pal +++ b/graphics/pokemon/deoxys/speed/normal.pal @@ -6,9 +6,9 @@ JASC-PAL 80 144 176 104 200 224 96 56 56 -248 112 72 +255 115 74 24 24 24 -192 104 104 +204 65 65 192 192 208 152 96 176 248 248 248 diff --git a/graphics/pokemon/dewpider/icon.png b/graphics/pokemon/dewpider/icon.png index bcf5707d3264..2cc98e2a367a 100644 Binary files a/graphics/pokemon/dewpider/icon.png and b/graphics/pokemon/dewpider/icon.png differ diff --git a/graphics/pokemon/dhelmise/icon.png b/graphics/pokemon/dhelmise/icon.png index 07b0c4d1803b..fd7e83627fbc 100644 Binary files a/graphics/pokemon/dhelmise/icon.png and b/graphics/pokemon/dhelmise/icon.png differ diff --git a/graphics/pokemon/diglett/alola/icon.png b/graphics/pokemon/diglett/alola/icon.png index 1b575078a348..ccde6cb2a3c5 100644 Binary files a/graphics/pokemon/diglett/alola/icon.png and b/graphics/pokemon/diglett/alola/icon.png differ diff --git a/graphics/pokemon/drampa/icon.png b/graphics/pokemon/drampa/icon.png index 5550dcb742d5..59428b634e98 100644 Binary files a/graphics/pokemon/drampa/icon.png and b/graphics/pokemon/drampa/icon.png differ diff --git a/graphics/pokemon/drilbur/overworld.png b/graphics/pokemon/drilbur/overworld.png index 9d1c7ddcf8dc..981e575fc1a3 100644 Binary files a/graphics/pokemon/drilbur/overworld.png and b/graphics/pokemon/drilbur/overworld.png differ diff --git a/graphics/pokemon/drilbur/overworld_normal.pal b/graphics/pokemon/drilbur/overworld_normal.pal index 34ab39137a68..9d33ec625065 100644 --- a/graphics/pokemon/drilbur/overworld_normal.pal +++ b/graphics/pokemon/drilbur/overworld_normal.pal @@ -5,7 +5,7 @@ JASC-PAL 40 40 40 40 40 40 11 11 11 -55 55 55 +43 43 43 55 55 55 87 87 87 0 0 0 diff --git a/graphics/pokemon/dugtrio/alola/icon.png b/graphics/pokemon/dugtrio/alola/icon.png index 2a409cb8d023..3b10a41c6b4e 100644 Binary files a/graphics/pokemon/dugtrio/alola/icon.png and b/graphics/pokemon/dugtrio/alola/icon.png differ diff --git a/graphics/pokemon/emboar/overworld.png b/graphics/pokemon/emboar/overworld.png index 06e17288d7ea..e647d062c3aa 100644 Binary files a/graphics/pokemon/emboar/overworld.png and b/graphics/pokemon/emboar/overworld.png differ diff --git a/graphics/pokemon/emboar/overworld_normal.pal b/graphics/pokemon/emboar/overworld_normal.pal index e9f672d506f8..e507a90ca903 100644 --- a/graphics/pokemon/emboar/overworld_normal.pal +++ b/graphics/pokemon/emboar/overworld_normal.pal @@ -6,14 +6,14 @@ JASC-PAL 5 5 5 48 48 48 111 40 1 -216 85 36 -188 82 31 +224 88 25 +184 80 32 119 19 12 -215 195 196 +240 240 240 230 49 41 -237 172 8 -180 139 32 +232 184 8 +176 136 32 123 90 8 -0 0 0 -0 0 0 +160 56 48 +64 64 64 0 0 0 diff --git a/graphics/pokemon/emboar/overworld_shiny.pal b/graphics/pokemon/emboar/overworld_shiny.pal index 1c5459473dc7..8fa173f591d6 100644 --- a/graphics/pokemon/emboar/overworld_shiny.pal +++ b/graphics/pokemon/emboar/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -41 41 41 +32 32 32 5 5 5 -41 41 41 +48 48 48 117 70 5 229 130 31 -41 41 41 -41 41 41 -229 130 31 +168 96 40 +49 53 92 +240 240 240 128 152 224 151 195 221 128 152 224 -117 70 5 -0 0 0 -0 0 0 +64 72 144 +96 112 184 +61 61 61 0 0 0 diff --git a/graphics/pokemon/exeggutor/alola/icon.png b/graphics/pokemon/exeggutor/alola/icon.png index 723d0a4ead44..49b788b715ee 100644 Binary files a/graphics/pokemon/exeggutor/alola/icon.png and b/graphics/pokemon/exeggutor/alola/icon.png differ diff --git a/graphics/pokemon/farfetchd/overworld.png b/graphics/pokemon/farfetchd/overworld.png index 46aec0976444..63d29215b729 100644 Binary files a/graphics/pokemon/farfetchd/overworld.png and b/graphics/pokemon/farfetchd/overworld.png differ diff --git a/graphics/pokemon/fezandipiti/back.png b/graphics/pokemon/fezandipiti/back.png index 45834050477c..4ca492548109 100644 Binary files a/graphics/pokemon/fezandipiti/back.png and b/graphics/pokemon/fezandipiti/back.png differ diff --git a/graphics/pokemon/fezandipiti/front.png b/graphics/pokemon/fezandipiti/front.png index fc841ec39500..1ff68f5004dd 100644 Binary files a/graphics/pokemon/fezandipiti/front.png and b/graphics/pokemon/fezandipiti/front.png differ diff --git a/graphics/pokemon/fezandipiti/normal.pal b/graphics/pokemon/fezandipiti/normal.pal index ac9c005324cf..a34688fc3f51 100644 --- a/graphics/pokemon/fezandipiti/normal.pal +++ b/graphics/pokemon/fezandipiti/normal.pal @@ -1,18 +1,19 @@ JASC-PAL 0100 -15 -152 208 160 -167 135 48 -118 61 41 -238 204 45 +16 +153 211 165 26 29 28 -78 73 71 45 45 45 -146 57 119 -202 103 162 +69 37 29 +118 61 41 90 33 73 +78 73 71 192 78 22 -254 254 254 -164 175 176 +146 57 119 +167 135 48 +238 204 45 +202 103 162 +179 177 162 16 16 16 -69 37 29 +254 254 254 +0 0 0 diff --git a/graphics/pokemon/fezandipiti/shiny.pal b/graphics/pokemon/fezandipiti/shiny.pal index 673473f5c0f4..b8f4918787e7 100644 --- a/graphics/pokemon/fezandipiti/shiny.pal +++ b/graphics/pokemon/fezandipiti/shiny.pal @@ -1,18 +1,19 @@ JASC-PAL 0100 -15 -152 208 160 -167 135 48 -118 61 41 -238 204 45 +16 +153 211 165 26 29 28 -59 63 133 -36 40 99 -146 57 119 -202 103 162 +51 48 101 +69 37 29 +118 61 41 90 33 73 +71 61 199 192 78 22 -254 254 254 -164 175 176 +146 57 119 +167 135 48 +238 204 45 +202 103 162 +179 177 162 16 16 16 -69 37 29 +254 254 254 +0 0 0 diff --git a/graphics/pokemon/floette/eternal/icon.png b/graphics/pokemon/floette/eternal/icon.png index 32f7face1f8b..4874a7720e54 100644 Binary files a/graphics/pokemon/floette/eternal/icon.png and b/graphics/pokemon/floette/eternal/icon.png differ diff --git a/graphics/pokemon/fomantis/icon.png b/graphics/pokemon/fomantis/icon.png index 2604f517d27c..d26f29932ca0 100644 Binary files a/graphics/pokemon/fomantis/icon.png and b/graphics/pokemon/fomantis/icon.png differ diff --git a/graphics/pokemon/furfrou/dandy_trim/icon.png b/graphics/pokemon/furfrou/dandy_trim/icon.png index a54f4fa4a4a9..4903feef719b 100644 Binary files a/graphics/pokemon/furfrou/dandy_trim/icon.png and b/graphics/pokemon/furfrou/dandy_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/debutante_trim/icon.png b/graphics/pokemon/furfrou/debutante_trim/icon.png index 02a350fb2e15..57c08949a3e8 100644 Binary files a/graphics/pokemon/furfrou/debutante_trim/icon.png and b/graphics/pokemon/furfrou/debutante_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/diamond_trim/icon.png b/graphics/pokemon/furfrou/diamond_trim/icon.png index 2acd3220d359..815332baf34f 100644 Binary files a/graphics/pokemon/furfrou/diamond_trim/icon.png and b/graphics/pokemon/furfrou/diamond_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/heart_trim/icon.png b/graphics/pokemon/furfrou/heart_trim/icon.png index e065e47667a0..d779ea9c2c8b 100644 Binary files a/graphics/pokemon/furfrou/heart_trim/icon.png and b/graphics/pokemon/furfrou/heart_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/kabuki_trim/icon.png b/graphics/pokemon/furfrou/kabuki_trim/icon.png index b3cad982e8bb..6b3527207dc1 100644 Binary files a/graphics/pokemon/furfrou/kabuki_trim/icon.png and b/graphics/pokemon/furfrou/kabuki_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/la_reine_trim/icon.png b/graphics/pokemon/furfrou/la_reine_trim/icon.png index 15aeb37e1b35..6e9384aaf664 100644 Binary files a/graphics/pokemon/furfrou/la_reine_trim/icon.png and b/graphics/pokemon/furfrou/la_reine_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/matron_trim/icon.png b/graphics/pokemon/furfrou/matron_trim/icon.png index 88384830e866..098b909623fc 100644 Binary files a/graphics/pokemon/furfrou/matron_trim/icon.png and b/graphics/pokemon/furfrou/matron_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/pharaoh_trim/icon.png b/graphics/pokemon/furfrou/pharaoh_trim/icon.png index cecb8f1655fb..ec2f4c1df02c 100644 Binary files a/graphics/pokemon/furfrou/pharaoh_trim/icon.png and b/graphics/pokemon/furfrou/pharaoh_trim/icon.png differ diff --git a/graphics/pokemon/furfrou/star_trim/icon.png b/graphics/pokemon/furfrou/star_trim/icon.png index acb3a5ed6ce3..551c32addf3e 100644 Binary files a/graphics/pokemon/furfrou/star_trim/icon.png and b/graphics/pokemon/furfrou/star_trim/icon.png differ diff --git a/graphics/pokemon/geodude/alola/icon.png b/graphics/pokemon/geodude/alola/icon.png index 1a5f9699716f..6a4cbd5158a7 100644 Binary files a/graphics/pokemon/geodude/alola/icon.png and b/graphics/pokemon/geodude/alola/icon.png differ diff --git a/graphics/pokemon/gigalith/overworld.png b/graphics/pokemon/gigalith/overworld.png index 8e5b2b7b3532..d84932ecea47 100644 Binary files a/graphics/pokemon/gigalith/overworld.png and b/graphics/pokemon/gigalith/overworld.png differ diff --git a/graphics/pokemon/golem/alola/icon.png b/graphics/pokemon/golem/alola/icon.png index e796f88842df..ccaa2714e850 100644 Binary files a/graphics/pokemon/golem/alola/icon.png and b/graphics/pokemon/golem/alola/icon.png differ diff --git a/graphics/pokemon/golisopod/icon.png b/graphics/pokemon/golisopod/icon.png index 37ee08049511..7ebe16a529db 100644 Binary files a/graphics/pokemon/golisopod/icon.png and b/graphics/pokemon/golisopod/icon.png differ diff --git a/graphics/pokemon/graveler/alola/icon.png b/graphics/pokemon/graveler/alola/icon.png index c0a7557ca05d..da15318b9694 100644 Binary files a/graphics/pokemon/graveler/alola/icon.png and b/graphics/pokemon/graveler/alola/icon.png differ diff --git a/graphics/pokemon/greninja/ash/icon.png b/graphics/pokemon/greninja/ash/icon.png index df9595619fa4..dc10f4b59b1e 100644 Binary files a/graphics/pokemon/greninja/ash/icon.png and b/graphics/pokemon/greninja/ash/icon.png differ diff --git a/graphics/pokemon/grimer/alola/icon.png b/graphics/pokemon/grimer/alola/icon.png index 09d83cb95e7b..38ba79b2dcef 100644 Binary files a/graphics/pokemon/grimer/alola/icon.png and b/graphics/pokemon/grimer/alola/icon.png differ diff --git a/graphics/pokemon/grubbin/icon.png b/graphics/pokemon/grubbin/icon.png index 96071bf8fbb2..4ff57b87c51c 100644 Binary files a/graphics/pokemon/grubbin/icon.png and b/graphics/pokemon/grubbin/icon.png differ diff --git a/graphics/pokemon/gumshoos/icon.png b/graphics/pokemon/gumshoos/icon.png index ac2bd83928db..6421d338e4b0 100644 Binary files a/graphics/pokemon/gumshoos/icon.png and b/graphics/pokemon/gumshoos/icon.png differ diff --git a/graphics/pokemon/guzzlord/icon.png b/graphics/pokemon/guzzlord/icon.png index 25e862d788a8..94ef70d8a24e 100644 Binary files a/graphics/pokemon/guzzlord/icon.png and b/graphics/pokemon/guzzlord/icon.png differ diff --git a/graphics/pokemon/hakamo_o/icon.png b/graphics/pokemon/hakamo_o/icon.png index 4836770537e3..90986aa3d600 100644 Binary files a/graphics/pokemon/hakamo_o/icon.png and b/graphics/pokemon/hakamo_o/icon.png differ diff --git a/graphics/pokemon/herdier/overworld.png b/graphics/pokemon/herdier/overworld.png index 51e2a2207bb9..de47a0ba7f4c 100644 Binary files a/graphics/pokemon/herdier/overworld.png and b/graphics/pokemon/herdier/overworld.png differ diff --git a/graphics/pokemon/herdier/overworld_shiny.pal b/graphics/pokemon/herdier/overworld_shiny.pal index 4713003a789c..0d9a690928b4 100644 --- a/graphics/pokemon/herdier/overworld_shiny.pal +++ b/graphics/pokemon/herdier/overworld_shiny.pal @@ -2,7 +2,7 @@ JASC-PAL 0100 16 152 208 160 -54 54 78 +56 56 56 0 0 0 64 64 64 96 72 24 diff --git a/graphics/pokemon/incineroar/icon.png b/graphics/pokemon/incineroar/icon.png index 020c549ecb14..a82408242197 100644 Binary files a/graphics/pokemon/incineroar/icon.png and b/graphics/pokemon/incineroar/icon.png differ diff --git a/graphics/pokemon/inteleon/gmax/icon.png b/graphics/pokemon/inteleon/gmax/icon.png index a27bf3f1c8d1..334ce1544074 100644 Binary files a/graphics/pokemon/inteleon/gmax/icon.png and b/graphics/pokemon/inteleon/gmax/icon.png differ diff --git a/graphics/pokemon/jangmo_o/icon.png b/graphics/pokemon/jangmo_o/icon.png index 0a8a2c2d03de..bbc7db29453e 100644 Binary files a/graphics/pokemon/jangmo_o/icon.png and b/graphics/pokemon/jangmo_o/icon.png differ diff --git a/graphics/pokemon/kartana/icon.png b/graphics/pokemon/kartana/icon.png index 7d0b82499eff..bdf3ec3a516d 100644 Binary files a/graphics/pokemon/kartana/icon.png and b/graphics/pokemon/kartana/icon.png differ diff --git a/graphics/pokemon/komala/icon.png b/graphics/pokemon/komala/icon.png index 6935e996ce6d..96af23fe188f 100644 Binary files a/graphics/pokemon/komala/icon.png and b/graphics/pokemon/komala/icon.png differ diff --git a/graphics/pokemon/kommo_o/icon.png b/graphics/pokemon/kommo_o/icon.png index 3acaf5329242..2a0ba757f8c7 100644 Binary files a/graphics/pokemon/kommo_o/icon.png and b/graphics/pokemon/kommo_o/icon.png differ diff --git a/graphics/pokemon/liepard/overworld.png b/graphics/pokemon/liepard/overworld.png index eb6611bf8456..804cdb39d699 100644 Binary files a/graphics/pokemon/liepard/overworld.png and b/graphics/pokemon/liepard/overworld.png differ diff --git a/graphics/pokemon/litten/icon.png b/graphics/pokemon/litten/icon.png index 5602732b434b..7867b32c6955 100644 Binary files a/graphics/pokemon/litten/icon.png and b/graphics/pokemon/litten/icon.png differ diff --git a/graphics/pokemon/lunala/icon.png b/graphics/pokemon/lunala/icon.png index 036b9b37197b..55002ed924dd 100644 Binary files a/graphics/pokemon/lunala/icon.png and b/graphics/pokemon/lunala/icon.png differ diff --git a/graphics/pokemon/lurantis/icon.png b/graphics/pokemon/lurantis/icon.png index 893f651b0371..f77d4e1e4866 100644 Binary files a/graphics/pokemon/lurantis/icon.png and b/graphics/pokemon/lurantis/icon.png differ diff --git a/graphics/pokemon/lycanroc/dusk/icon.png b/graphics/pokemon/lycanroc/dusk/icon.png index 65d8394f4e67..7b860c14ce9e 100644 Binary files a/graphics/pokemon/lycanroc/dusk/icon.png and b/graphics/pokemon/lycanroc/dusk/icon.png differ diff --git a/graphics/pokemon/lycanroc/icon.png b/graphics/pokemon/lycanroc/icon.png index 8ae43133740c..50a6a2e9d8ea 100644 Binary files a/graphics/pokemon/lycanroc/icon.png and b/graphics/pokemon/lycanroc/icon.png differ diff --git a/graphics/pokemon/lycanroc/midnight/icon.png b/graphics/pokemon/lycanroc/midnight/icon.png index f6b98c949de5..33bdba204e61 100644 Binary files a/graphics/pokemon/lycanroc/midnight/icon.png and b/graphics/pokemon/lycanroc/midnight/icon.png differ diff --git a/graphics/pokemon/magearna/icon.png b/graphics/pokemon/magearna/icon.png index cfb4c0664798..6a421d6ada04 100644 Binary files a/graphics/pokemon/magearna/icon.png and b/graphics/pokemon/magearna/icon.png differ diff --git a/graphics/pokemon/magearna/original_color/icon.png b/graphics/pokemon/magearna/original_color/icon.png index 5e97b3ccb37d..0f1b1e905213 100644 Binary files a/graphics/pokemon/magearna/original_color/icon.png and b/graphics/pokemon/magearna/original_color/icon.png differ diff --git a/graphics/pokemon/mareanie/icon.png b/graphics/pokemon/mareanie/icon.png index 7b7dc44fb219..7464483cfe5f 100644 Binary files a/graphics/pokemon/mareanie/icon.png and b/graphics/pokemon/mareanie/icon.png differ diff --git a/graphics/pokemon/marowak/alola/icon.png b/graphics/pokemon/marowak/alola/icon.png index 3ea2a868c353..d434c92fb702 100644 Binary files a/graphics/pokemon/marowak/alola/icon.png and b/graphics/pokemon/marowak/alola/icon.png differ diff --git a/graphics/pokemon/marshadow/icon.png b/graphics/pokemon/marshadow/icon.png index e7fb5674d396..b8d05ba2993e 100644 Binary files a/graphics/pokemon/marshadow/icon.png and b/graphics/pokemon/marshadow/icon.png differ diff --git a/graphics/pokemon/maschiff/back.png b/graphics/pokemon/maschiff/back.png index 6a6a45eb463e..4891b2371a54 100644 Binary files a/graphics/pokemon/maschiff/back.png and b/graphics/pokemon/maschiff/back.png differ diff --git a/graphics/pokemon/maschiff/front.png b/graphics/pokemon/maschiff/front.png index 05f724ec6dd3..c06b23028e47 100644 Binary files a/graphics/pokemon/maschiff/front.png and b/graphics/pokemon/maschiff/front.png differ diff --git a/graphics/pokemon/maschiff/normal.pal b/graphics/pokemon/maschiff/normal.pal index 3c397173c3e8..7de2cd0927fc 100644 --- a/graphics/pokemon/maschiff/normal.pal +++ b/graphics/pokemon/maschiff/normal.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -156 210 164 -255 255 255 -255 193 11 -180 178 180 -238 113 24 -255 157 90 -213 141 8 -106 36 32 -98 97 98 -213 117 106 -90 64 82 -172 85 74 -8 12 8 -65 44 57 -238 170 148 -164 97 49 +153 211 165 +36 30 33 +57 45 53 +71 37 41 +86 67 79 +121 117 100 +141 86 46 +199 121 35 +251 111 49 +129 67 75 +195 115 113 +253 201 67 +16 16 16 +253 242 223 +0 0 0 +0 0 0 diff --git a/graphics/pokemon/maschiff/shiny.pal b/graphics/pokemon/maschiff/shiny.pal index 23f5bf0a74a1..cb13ff86a9b0 100644 --- a/graphics/pokemon/maschiff/shiny.pal +++ b/graphics/pokemon/maschiff/shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -156 210 164 -255 255 255 -120 98 112 -180 178 180 -238 113 24 -255 157 90 -81 65 73 -92 77 102 -98 97 98 -173 157 191 -90 64 82 -129 114 142 -8 12 8 -65 44 57 -201 195 216 -63 47 59 +153 211 165 +36 30 33 +57 45 53 +62 55 70 +86 67 79 +121 117 100 +63 50 58 +87 70 82 +251 111 49 +102 92 114 +171 139 201 +119 96 110 +16 16 16 +253 242 223 +0 0 0 +0 0 0 diff --git a/graphics/pokemon/melmetal/icon.png b/graphics/pokemon/melmetal/icon.png index fa70c6b6b507..20382c2d80fa 100644 Binary files a/graphics/pokemon/melmetal/icon.png and b/graphics/pokemon/melmetal/icon.png differ diff --git a/graphics/pokemon/melmetal/overworld.png b/graphics/pokemon/melmetal/overworld.png index 4be020a5c6a8..e8097644ad16 100644 Binary files a/graphics/pokemon/melmetal/overworld.png and b/graphics/pokemon/melmetal/overworld.png differ diff --git a/graphics/pokemon/melmetal/overworld_normal.pal b/graphics/pokemon/melmetal/overworld_normal.pal index 28e459319267..d9b329362bea 100644 --- a/graphics/pokemon/melmetal/overworld_normal.pal +++ b/graphics/pokemon/melmetal/overworld_normal.pal @@ -1,7 +1,7 @@ JASC-PAL 0100 16 -255 255 255 +120 255 255 254 235 185 220 220 218 235 192 100 @@ -16,4 +16,4 @@ JASC-PAL 64 64 64 45 43 43 8 8 8 -0 0 0 +255 255 255 diff --git a/graphics/pokemon/melmetal/overworld_shiny.pal b/graphics/pokemon/melmetal/overworld_shiny.pal index 6d1c75c9bbf3..4f5321a06227 100644 --- a/graphics/pokemon/melmetal/overworld_shiny.pal +++ b/graphics/pokemon/melmetal/overworld_shiny.pal @@ -16,4 +16,4 @@ JASC-PAL 64 64 64 45 43 43 8 8 8 -0 0 0 +255 255 255 diff --git a/graphics/pokemon/meltan/icon.png b/graphics/pokemon/meltan/icon.png index 17fb4f96bd70..51da112566b9 100644 Binary files a/graphics/pokemon/meltan/icon.png and b/graphics/pokemon/meltan/icon.png differ diff --git a/graphics/pokemon/meowth/alola/icon.png b/graphics/pokemon/meowth/alola/icon.png index d4b80eb6b461..f2b5d00cbe0f 100644 Binary files a/graphics/pokemon/meowth/alola/icon.png and b/graphics/pokemon/meowth/alola/icon.png differ diff --git a/graphics/pokemon/mimikyu/busted/icon.png b/graphics/pokemon/mimikyu/busted/icon.png index 46bc43005958..58272ef8feb8 100644 Binary files a/graphics/pokemon/mimikyu/busted/icon.png and b/graphics/pokemon/mimikyu/busted/icon.png differ diff --git a/graphics/pokemon/mimikyu/icon.png b/graphics/pokemon/mimikyu/icon.png index 89c587683aff..73d110ca70d8 100644 Binary files a/graphics/pokemon/mimikyu/icon.png and b/graphics/pokemon/mimikyu/icon.png differ diff --git a/graphics/pokemon/minior/core/blue/icon.png b/graphics/pokemon/minior/core/blue/icon.png index 85ee89151770..60f670a1a84c 100644 Binary files a/graphics/pokemon/minior/core/blue/icon.png and b/graphics/pokemon/minior/core/blue/icon.png differ diff --git a/graphics/pokemon/minior/core/green/icon.png b/graphics/pokemon/minior/core/green/icon.png index f724e86aeb85..cf24afb332a2 100644 Binary files a/graphics/pokemon/minior/core/green/icon.png and b/graphics/pokemon/minior/core/green/icon.png differ diff --git a/graphics/pokemon/minior/core/indigo/icon.png b/graphics/pokemon/minior/core/indigo/icon.png index 4f2e531cedba..17a625ccd9fa 100644 Binary files a/graphics/pokemon/minior/core/indigo/icon.png and b/graphics/pokemon/minior/core/indigo/icon.png differ diff --git a/graphics/pokemon/minior/core/orange/icon.png b/graphics/pokemon/minior/core/orange/icon.png index 40509d6b5116..7418f1ec53f4 100644 Binary files a/graphics/pokemon/minior/core/orange/icon.png and b/graphics/pokemon/minior/core/orange/icon.png differ diff --git a/graphics/pokemon/minior/core/red/icon.png b/graphics/pokemon/minior/core/red/icon.png index 486dcdebd1c7..3d3880d7c3f9 100644 Binary files a/graphics/pokemon/minior/core/red/icon.png and b/graphics/pokemon/minior/core/red/icon.png differ diff --git a/graphics/pokemon/minior/core/violet/icon.png b/graphics/pokemon/minior/core/violet/icon.png index 4392bdf3b9e2..afa5589627aa 100644 Binary files a/graphics/pokemon/minior/core/violet/icon.png and b/graphics/pokemon/minior/core/violet/icon.png differ diff --git a/graphics/pokemon/minior/core/yellow/icon.png b/graphics/pokemon/minior/core/yellow/icon.png index f7dfb73362a7..ae71fd9a24c1 100644 Binary files a/graphics/pokemon/minior/core/yellow/icon.png and b/graphics/pokemon/minior/core/yellow/icon.png differ diff --git a/graphics/pokemon/morelull/icon.png b/graphics/pokemon/morelull/icon.png index 221ebe545728..1c50141e103a 100644 Binary files a/graphics/pokemon/morelull/icon.png and b/graphics/pokemon/morelull/icon.png differ diff --git a/graphics/pokemon/mudbray/icon.png b/graphics/pokemon/mudbray/icon.png index 0447096ecbb8..92094f19efe9 100644 Binary files a/graphics/pokemon/mudbray/icon.png and b/graphics/pokemon/mudbray/icon.png differ diff --git a/graphics/pokemon/mudsdale/icon.png b/graphics/pokemon/mudsdale/icon.png index 3146346ead84..8b2f118fbf4a 100644 Binary files a/graphics/pokemon/mudsdale/icon.png and b/graphics/pokemon/mudsdale/icon.png differ diff --git a/graphics/pokemon/muk/alola/icon.png b/graphics/pokemon/muk/alola/icon.png index d598fd728306..676a7999ee49 100644 Binary files a/graphics/pokemon/muk/alola/icon.png and b/graphics/pokemon/muk/alola/icon.png differ diff --git a/graphics/pokemon/munna/overworld.png b/graphics/pokemon/munna/overworld.png index 9dc20321457f..605379190d9d 100644 Binary files a/graphics/pokemon/munna/overworld.png and b/graphics/pokemon/munna/overworld.png differ diff --git a/graphics/pokemon/munna/overworld_shiny.pal b/graphics/pokemon/munna/overworld_shiny.pal index 04fb73d163e2..87653086551b 100644 --- a/graphics/pokemon/munna/overworld_shiny.pal +++ b/graphics/pokemon/munna/overworld_shiny.pal @@ -10,7 +10,7 @@ JASC-PAL 248 248 248 24 40 16 238 238 247 -208 24 80 +168 56 136 240 136 208 144 40 112 145 83 106 diff --git a/graphics/pokemon/musharna/overworld.png b/graphics/pokemon/musharna/overworld.png index aef3207b7e1a..081e4187e5c8 100644 Binary files a/graphics/pokemon/musharna/overworld.png and b/graphics/pokemon/musharna/overworld.png differ diff --git a/graphics/pokemon/musharna/overworld_normal.pal b/graphics/pokemon/musharna/overworld_normal.pal index f1b11dd773e3..cfcbd413f1dc 100644 --- a/graphics/pokemon/musharna/overworld_normal.pal +++ b/graphics/pokemon/musharna/overworld_normal.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -109 75 80 -145 83 106 +122 77 104 +145 74 100 225 112 161 -175 112 140 -97 66 145 +168 80 112 +83 62 115 42 47 74 -140 137 175 -134 96 184 +144 120 216 +104 96 160 252 188 219 -247 207 182 -207 150 111 +248 192 200 +200 152 144 0 0 0 160 175 128 -0 0 0 +152 88 96 0 0 0 diff --git a/graphics/pokemon/musharna/overworld_shiny.pal b/graphics/pokemon/musharna/overworld_shiny.pal index 6b5ab82193c0..01c9460d4a9d 100644 --- a/graphics/pokemon/musharna/overworld_shiny.pal +++ b/graphics/pokemon/musharna/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -109 75 80 -112 56 128 +88 72 128 +92 52 128 152 112 200 -175 112 140 +119 87 158 48 72 96 42 47 74 80 152 192 -64 120 192 +72 112 144 152 208 160 248 176 192 208 128 152 0 0 0 152 208 160 -0 0 0 +136 88 104 0 0 0 diff --git a/graphics/pokemon/naganadel/icon.png b/graphics/pokemon/naganadel/icon.png index 23204c5d18da..f1194b189e2a 100644 Binary files a/graphics/pokemon/naganadel/icon.png and b/graphics/pokemon/naganadel/icon.png differ diff --git a/graphics/pokemon/necrozma/dawn_wings/icon.png b/graphics/pokemon/necrozma/dawn_wings/icon.png index 25d24cb024eb..5644f2302600 100644 Binary files a/graphics/pokemon/necrozma/dawn_wings/icon.png and b/graphics/pokemon/necrozma/dawn_wings/icon.png differ diff --git a/graphics/pokemon/necrozma/dusk_mane/icon.png b/graphics/pokemon/necrozma/dusk_mane/icon.png index c188b1e3ca04..c60f222f76a5 100644 Binary files a/graphics/pokemon/necrozma/dusk_mane/icon.png and b/graphics/pokemon/necrozma/dusk_mane/icon.png differ diff --git a/graphics/pokemon/necrozma/icon.png b/graphics/pokemon/necrozma/icon.png index 1d4283fddc9f..603f1f4fa00f 100644 Binary files a/graphics/pokemon/necrozma/icon.png and b/graphics/pokemon/necrozma/icon.png differ diff --git a/graphics/pokemon/necrozma/ultra/icon.png b/graphics/pokemon/necrozma/ultra/icon.png index 1c63345bc858..790be2e0c258 100644 Binary files a/graphics/pokemon/necrozma/ultra/icon.png and b/graphics/pokemon/necrozma/ultra/icon.png differ diff --git a/graphics/pokemon/nihilego/icon.png b/graphics/pokemon/nihilego/icon.png index 6e8f855d59ca..3be83cab2f4e 100644 Binary files a/graphics/pokemon/nihilego/icon.png and b/graphics/pokemon/nihilego/icon.png differ diff --git a/graphics/pokemon/ninetales/alola/icon.png b/graphics/pokemon/ninetales/alola/icon.png index 71ac99d5a723..f433689887d9 100644 Binary files a/graphics/pokemon/ninetales/alola/icon.png and b/graphics/pokemon/ninetales/alola/icon.png differ diff --git a/graphics/pokemon/oranguru/icon.png b/graphics/pokemon/oranguru/icon.png index da7abe984b6e..99b8c13f8fdd 100644 Binary files a/graphics/pokemon/oranguru/icon.png and b/graphics/pokemon/oranguru/icon.png differ diff --git a/graphics/pokemon/oricorio/icon.png b/graphics/pokemon/oricorio/icon.png index 80936904c099..a5f53870fe5a 100644 Binary files a/graphics/pokemon/oricorio/icon.png and b/graphics/pokemon/oricorio/icon.png differ diff --git a/graphics/pokemon/oricorio/pau/icon.png b/graphics/pokemon/oricorio/pau/icon.png index 98040bf38dd0..72a009bd5581 100644 Binary files a/graphics/pokemon/oricorio/pau/icon.png and b/graphics/pokemon/oricorio/pau/icon.png differ diff --git a/graphics/pokemon/oricorio/pom_pom/icon.png b/graphics/pokemon/oricorio/pom_pom/icon.png index b60855f9188f..d757b0564aa6 100644 Binary files a/graphics/pokemon/oricorio/pom_pom/icon.png and b/graphics/pokemon/oricorio/pom_pom/icon.png differ diff --git a/graphics/pokemon/oricorio/sensu/icon.png b/graphics/pokemon/oricorio/sensu/icon.png index b8423c31fc13..3491f6ee0296 100644 Binary files a/graphics/pokemon/oricorio/sensu/icon.png and b/graphics/pokemon/oricorio/sensu/icon.png differ diff --git a/graphics/pokemon/palossand/icon.png b/graphics/pokemon/palossand/icon.png index 3131f2c20540..80f64f8b00ae 100644 Binary files a/graphics/pokemon/palossand/icon.png and b/graphics/pokemon/palossand/icon.png differ diff --git a/graphics/pokemon/palpitoad/overworld.png b/graphics/pokemon/palpitoad/overworld.png index 3be06ec27571..dda419e276c1 100644 Binary files a/graphics/pokemon/palpitoad/overworld.png and b/graphics/pokemon/palpitoad/overworld.png differ diff --git a/graphics/pokemon/palpitoad/overworld_normal.pal b/graphics/pokemon/palpitoad/overworld_normal.pal index 4d5d03566cbd..7116f735ee71 100644 --- a/graphics/pokemon/palpitoad/overworld_normal.pal +++ b/graphics/pokemon/palpitoad/overworld_normal.pal @@ -14,6 +14,6 @@ JASC-PAL 191 147 121 239 215 196 138 79 63 -0 0 0 +224 224 224 0 0 0 0 0 0 diff --git a/graphics/pokemon/palpitoad/overworld_shiny.pal b/graphics/pokemon/palpitoad/overworld_shiny.pal index 46d834cac643..cfd54885c9d5 100644 --- a/graphics/pokemon/palpitoad/overworld_shiny.pal +++ b/graphics/pokemon/palpitoad/overworld_shiny.pal @@ -5,15 +5,15 @@ JASC-PAL 0 0 0 96 96 94 65 65 65 -188 99 24 +248 168 16 15 87 72 38 39 41 40 168 168 8 192 208 -120 80 8 -222 196 194 +161 89 22 +176 136 128 222 196 194 96 96 94 -0 0 0 +224 224 224 0 0 0 0 0 0 diff --git a/graphics/pokemon/panpour/overworld.png b/graphics/pokemon/panpour/overworld.png index e02358cf2dd6..698ec1737fd2 100644 Binary files a/graphics/pokemon/panpour/overworld.png and b/graphics/pokemon/panpour/overworld.png differ diff --git a/graphics/pokemon/panpour/overworld_normal.pal b/graphics/pokemon/panpour/overworld_normal.pal index 99ad9dc501d7..31d63b727ec6 100644 --- a/graphics/pokemon/panpour/overworld_normal.pal +++ b/graphics/pokemon/panpour/overworld_normal.pal @@ -2,7 +2,7 @@ JASC-PAL 0100 16 152 208 160 -0 57 115 +26 54 82 24 139 172 41 180 222 0 0 0 diff --git a/graphics/pokemon/pansage/overworld.png b/graphics/pokemon/pansage/overworld.png index 6addd12e2069..3e884320afe3 100644 Binary files a/graphics/pokemon/pansage/overworld.png and b/graphics/pokemon/pansage/overworld.png differ diff --git a/graphics/pokemon/pansear/overworld.png b/graphics/pokemon/pansear/overworld.png index 0962330b53fd..270f79180272 100644 Binary files a/graphics/pokemon/pansear/overworld.png and b/graphics/pokemon/pansear/overworld.png differ diff --git a/graphics/pokemon/passimian/icon.png b/graphics/pokemon/passimian/icon.png index 6daf24ccb6f2..1eed7c54129b 100644 Binary files a/graphics/pokemon/passimian/icon.png and b/graphics/pokemon/passimian/icon.png differ diff --git a/graphics/pokemon/patrat/overworld.png b/graphics/pokemon/patrat/overworld.png index ea2df04dc1ae..8b6a34f19870 100644 Binary files a/graphics/pokemon/patrat/overworld.png and b/graphics/pokemon/patrat/overworld.png differ diff --git a/graphics/pokemon/persian/alola/icon.png b/graphics/pokemon/persian/alola/icon.png index 75348250d540..21ad48eb3146 100644 Binary files a/graphics/pokemon/persian/alola/icon.png and b/graphics/pokemon/persian/alola/icon.png differ diff --git a/graphics/pokemon/pheromosa/icon.png b/graphics/pokemon/pheromosa/icon.png index 4ab3a02a4e19..0ff38de88830 100644 Binary files a/graphics/pokemon/pheromosa/icon.png and b/graphics/pokemon/pheromosa/icon.png differ diff --git a/graphics/pokemon/pichu/spiky_eared/icon.png b/graphics/pokemon/pichu/spiky_eared/icon.png index acd0234e0f11..dbb47c84da30 100644 Binary files a/graphics/pokemon/pichu/spiky_eared/icon.png and b/graphics/pokemon/pichu/spiky_eared/icon.png differ diff --git a/graphics/pokemon/pidove/overworld.png b/graphics/pokemon/pidove/overworld.png index b55a13e39010..020027d44e4d 100644 Binary files a/graphics/pokemon/pidove/overworld.png and b/graphics/pokemon/pidove/overworld.png differ diff --git a/graphics/pokemon/pidove/overworld_normal.pal b/graphics/pokemon/pidove/overworld_normal.pal index 704bb5f94638..820bcb20cd5b 100644 --- a/graphics/pokemon/pidove/overworld_normal.pal +++ b/graphics/pokemon/pidove/overworld_normal.pal @@ -14,6 +14,6 @@ JASC-PAL 248 184 40 184 96 96 128 128 128 -172 172 172 +150 150 150 0 0 0 0 0 0 diff --git a/graphics/pokemon/pignite/overworld.png b/graphics/pokemon/pignite/overworld.png index 9ea0862b2d49..b6b97736b9d7 100644 Binary files a/graphics/pokemon/pignite/overworld.png and b/graphics/pokemon/pignite/overworld.png differ diff --git a/graphics/pokemon/pignite/overworld_normal.pal b/graphics/pokemon/pignite/overworld_normal.pal index 5cf1ee3ef0e5..1454fac04dc5 100644 --- a/graphics/pokemon/pignite/overworld_normal.pal +++ b/graphics/pokemon/pignite/overworld_normal.pal @@ -4,16 +4,16 @@ JASC-PAL 152 208 160 16 16 16 0 0 0 -82 49 41 +80 48 40 57 37 37 -189 90 49 +209 95 46 123 57 41 -232 106 43 -210 182 96 -24 32 40 -83 79 60 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +232 112 40 +232 192 56 +56 32 32 +80 48 40 +232 232 248 +200 64 56 +72 72 72 +41 41 41 0 0 0 diff --git a/graphics/pokemon/pignite/overworld_shiny.pal b/graphics/pokemon/pignite/overworld_shiny.pal index 21a321291465..8d967d10b737 100644 --- a/graphics/pokemon/pignite/overworld_shiny.pal +++ b/graphics/pokemon/pignite/overworld_shiny.pal @@ -6,14 +6,14 @@ JASC-PAL 0 0 0 48 56 72 42 48 55 -120 104 240 -101 69 51 +184 136 24 +120 88 40 232 160 32 -204 156 214 +160 144 232 42 48 55 48 56 72 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +232 232 248 +212 121 189 +88 48 40 +56 32 32 0 0 0 diff --git a/graphics/pokemon/pikachu/alola/icon.png b/graphics/pokemon/pikachu/alola/icon.png index b9ba5f757f90..0634df1ad715 100644 Binary files a/graphics/pokemon/pikachu/alola/icon.png and b/graphics/pokemon/pikachu/alola/icon.png differ diff --git a/graphics/pokemon/pikachu/belle/icon.png b/graphics/pokemon/pikachu/belle/icon.png index b3c0f00b37d1..f19b2894547b 100644 Binary files a/graphics/pokemon/pikachu/belle/icon.png and b/graphics/pokemon/pikachu/belle/icon.png differ diff --git a/graphics/pokemon/pikachu/cosplay/icon.png b/graphics/pokemon/pikachu/cosplay/icon.png index c826dacab095..21d9172a1f95 100644 Binary files a/graphics/pokemon/pikachu/cosplay/icon.png and b/graphics/pokemon/pikachu/cosplay/icon.png differ diff --git a/graphics/pokemon/pikachu/hoenn/icon.png b/graphics/pokemon/pikachu/hoenn/icon.png index e5f8bfe206c6..5b9cbb2ba6ff 100644 Binary files a/graphics/pokemon/pikachu/hoenn/icon.png and b/graphics/pokemon/pikachu/hoenn/icon.png differ diff --git a/graphics/pokemon/pikachu/kalos/icon.png b/graphics/pokemon/pikachu/kalos/icon.png index c903ea9f3f8c..2aae11d524b0 100644 Binary files a/graphics/pokemon/pikachu/kalos/icon.png and b/graphics/pokemon/pikachu/kalos/icon.png differ diff --git a/graphics/pokemon/pikachu/libre/icon.png b/graphics/pokemon/pikachu/libre/icon.png index c1163a161970..ef6e8f1553c9 100644 Binary files a/graphics/pokemon/pikachu/libre/icon.png and b/graphics/pokemon/pikachu/libre/icon.png differ diff --git a/graphics/pokemon/pikachu/original/icon.png b/graphics/pokemon/pikachu/original/icon.png index d84764b65c1b..d4b80f3dc71a 100644 Binary files a/graphics/pokemon/pikachu/original/icon.png and b/graphics/pokemon/pikachu/original/icon.png differ diff --git a/graphics/pokemon/pikachu/phd/icon.png b/graphics/pokemon/pikachu/phd/icon.png index f0b66bccf844..3d228c4275c3 100644 Binary files a/graphics/pokemon/pikachu/phd/icon.png and b/graphics/pokemon/pikachu/phd/icon.png differ diff --git a/graphics/pokemon/pikachu/pop_star/icon.png b/graphics/pokemon/pikachu/pop_star/icon.png index eb9b49e70af9..1775f78db141 100644 Binary files a/graphics/pokemon/pikachu/pop_star/icon.png and b/graphics/pokemon/pikachu/pop_star/icon.png differ diff --git a/graphics/pokemon/pikachu/rock_star/icon.png b/graphics/pokemon/pikachu/rock_star/icon.png index 2c8d144d6074..89025f0f3eb7 100644 Binary files a/graphics/pokemon/pikachu/rock_star/icon.png and b/graphics/pokemon/pikachu/rock_star/icon.png differ diff --git a/graphics/pokemon/pikachu/sinnoh/icon.png b/graphics/pokemon/pikachu/sinnoh/icon.png index 081ee6aae3a6..fbd66b0525a9 100644 Binary files a/graphics/pokemon/pikachu/sinnoh/icon.png and b/graphics/pokemon/pikachu/sinnoh/icon.png differ diff --git a/graphics/pokemon/pikachu/starter/icon.png b/graphics/pokemon/pikachu/starter/icon.png index 891f0d1b3e87..737fababd7d4 100644 Binary files a/graphics/pokemon/pikachu/starter/icon.png and b/graphics/pokemon/pikachu/starter/icon.png differ diff --git a/graphics/pokemon/pikachu/unova/icon.png b/graphics/pokemon/pikachu/unova/icon.png index b6427a5ec2a7..427a38c6d605 100644 Binary files a/graphics/pokemon/pikachu/unova/icon.png and b/graphics/pokemon/pikachu/unova/icon.png differ diff --git a/graphics/pokemon/pikachu/world/icon.png b/graphics/pokemon/pikachu/world/icon.png index 260e29cda2c5..58c4ed1f4883 100644 Binary files a/graphics/pokemon/pikachu/world/icon.png and b/graphics/pokemon/pikachu/world/icon.png differ diff --git a/graphics/pokemon/pikipek/icon.png b/graphics/pokemon/pikipek/icon.png index 291e148f1a47..9a65234d8d1e 100644 Binary files a/graphics/pokemon/pikipek/icon.png and b/graphics/pokemon/pikipek/icon.png differ diff --git a/graphics/pokemon/poipole/icon.png b/graphics/pokemon/poipole/icon.png index dce46b073d3e..b1ab69e8fb8a 100644 Binary files a/graphics/pokemon/poipole/icon.png and b/graphics/pokemon/poipole/icon.png differ diff --git a/graphics/pokemon/popplio/icon.png b/graphics/pokemon/popplio/icon.png index c35b74d2d970..f2eb184651bf 100644 Binary files a/graphics/pokemon/popplio/icon.png and b/graphics/pokemon/popplio/icon.png differ diff --git a/graphics/pokemon/primarina/icon.png b/graphics/pokemon/primarina/icon.png index d642cf12b24f..1b56f7690cb1 100644 Binary files a/graphics/pokemon/primarina/icon.png and b/graphics/pokemon/primarina/icon.png differ diff --git a/graphics/pokemon/purrloin/overworld.png b/graphics/pokemon/purrloin/overworld.png index dd0d58266ef6..b751a7f8ece8 100644 Binary files a/graphics/pokemon/purrloin/overworld.png and b/graphics/pokemon/purrloin/overworld.png differ diff --git a/graphics/pokemon/purrloin/overworld_shiny.pal b/graphics/pokemon/purrloin/overworld_shiny.pal index f1c5b242d017..92ba9739bf77 100644 --- a/graphics/pokemon/purrloin/overworld_shiny.pal +++ b/graphics/pokemon/purrloin/overworld_shiny.pal @@ -7,10 +7,10 @@ JASC-PAL 0 0 0 56 72 104 168 112 224 -216 216 56 -240 232 192 -232 232 248 +112 176 64 216 200 136 +232 232 248 +240 232 192 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/pyukumuku/icon.png b/graphics/pokemon/pyukumuku/icon.png index 2e3e04451d77..9ef614755858 100644 Binary files a/graphics/pokemon/pyukumuku/icon.png and b/graphics/pokemon/pyukumuku/icon.png differ diff --git a/graphics/pokemon/raichu/alola/icon.png b/graphics/pokemon/raichu/alola/icon.png index d005cf7e1de3..2098d83f95f0 100644 Binary files a/graphics/pokemon/raichu/alola/icon.png and b/graphics/pokemon/raichu/alola/icon.png differ diff --git a/graphics/pokemon/raticate/alola/icon.png b/graphics/pokemon/raticate/alola/icon.png index 4acd9d0404db..072c5ca6e449 100644 Binary files a/graphics/pokemon/raticate/alola/icon.png and b/graphics/pokemon/raticate/alola/icon.png differ diff --git a/graphics/pokemon/rattata/alola/icon.png b/graphics/pokemon/rattata/alola/icon.png index b13e1e9bb949..87c40fa445bf 100644 Binary files a/graphics/pokemon/rattata/alola/icon.png and b/graphics/pokemon/rattata/alola/icon.png differ diff --git a/graphics/pokemon/ribombee/icon.png b/graphics/pokemon/ribombee/icon.png index 10117f123441..46f0ba787cda 100644 Binary files a/graphics/pokemon/ribombee/icon.png and b/graphics/pokemon/ribombee/icon.png differ diff --git a/graphics/pokemon/rockruff/icon.png b/graphics/pokemon/rockruff/icon.png index 5df839ab5d32..6a7816898e6d 100644 Binary files a/graphics/pokemon/rockruff/icon.png and b/graphics/pokemon/rockruff/icon.png differ diff --git a/graphics/pokemon/rowlet/icon.png b/graphics/pokemon/rowlet/icon.png index 433666f6e186..725a5884f7b1 100644 Binary files a/graphics/pokemon/rowlet/icon.png and b/graphics/pokemon/rowlet/icon.png differ diff --git a/graphics/pokemon/salandit/icon.png b/graphics/pokemon/salandit/icon.png index e0c6309c7544..37fe8d7e755e 100644 Binary files a/graphics/pokemon/salandit/icon.png and b/graphics/pokemon/salandit/icon.png differ diff --git a/graphics/pokemon/salazzle/icon.png b/graphics/pokemon/salazzle/icon.png index db4edf2fc30b..e106d18c4d72 100644 Binary files a/graphics/pokemon/salazzle/icon.png and b/graphics/pokemon/salazzle/icon.png differ diff --git a/graphics/pokemon/sandshrew/alola/icon.png b/graphics/pokemon/sandshrew/alola/icon.png index a1cc049bdb95..ae93de08b63d 100644 Binary files a/graphics/pokemon/sandshrew/alola/icon.png and b/graphics/pokemon/sandshrew/alola/icon.png differ diff --git a/graphics/pokemon/sandslash/alola/icon.png b/graphics/pokemon/sandslash/alola/icon.png index 88cea6049b4e..9df450d1ed85 100644 Binary files a/graphics/pokemon/sandslash/alola/icon.png and b/graphics/pokemon/sandslash/alola/icon.png differ diff --git a/graphics/pokemon/sandygast/icon.png b/graphics/pokemon/sandygast/icon.png index 46167f5ab661..b4028109422a 100644 Binary files a/graphics/pokemon/sandygast/icon.png and b/graphics/pokemon/sandygast/icon.png differ diff --git a/graphics/pokemon/shiinotic/icon.png b/graphics/pokemon/shiinotic/icon.png index 510d61a97c21..68adb4ff3449 100644 Binary files a/graphics/pokemon/shiinotic/icon.png and b/graphics/pokemon/shiinotic/icon.png differ diff --git a/graphics/pokemon/silvally/icon.png b/graphics/pokemon/silvally/icon.png index 2ef6ae9ad718..954a4362b92d 100644 Binary files a/graphics/pokemon/silvally/icon.png and b/graphics/pokemon/silvally/icon.png differ diff --git a/graphics/pokemon/solgaleo/icon.png b/graphics/pokemon/solgaleo/icon.png index e7520c9bcf6d..62ed55d20531 100644 Binary files a/graphics/pokemon/solgaleo/icon.png and b/graphics/pokemon/solgaleo/icon.png differ diff --git a/graphics/pokemon/stakataka/icon.png b/graphics/pokemon/stakataka/icon.png index ad79ba34d888..359b1a248cc5 100644 Binary files a/graphics/pokemon/stakataka/icon.png and b/graphics/pokemon/stakataka/icon.png differ diff --git a/graphics/pokemon/steenee/icon.png b/graphics/pokemon/steenee/icon.png index 80531a631504..eea2c5a42a96 100644 Binary files a/graphics/pokemon/steenee/icon.png and b/graphics/pokemon/steenee/icon.png differ diff --git a/graphics/pokemon/stufful/icon.png b/graphics/pokemon/stufful/icon.png index de35247ae828..357d860f6346 100644 Binary files a/graphics/pokemon/stufful/icon.png and b/graphics/pokemon/stufful/icon.png differ diff --git a/graphics/pokemon/tapu_bulu/icon.png b/graphics/pokemon/tapu_bulu/icon.png index 69261acb3f04..9d329d825093 100644 Binary files a/graphics/pokemon/tapu_bulu/icon.png and b/graphics/pokemon/tapu_bulu/icon.png differ diff --git a/graphics/pokemon/tapu_fini/icon.png b/graphics/pokemon/tapu_fini/icon.png index fcd74bbd199c..623e1d428781 100644 Binary files a/graphics/pokemon/tapu_fini/icon.png and b/graphics/pokemon/tapu_fini/icon.png differ diff --git a/graphics/pokemon/tapu_koko/icon.png b/graphics/pokemon/tapu_koko/icon.png index 73470d55adc3..2c857e5aa22e 100644 Binary files a/graphics/pokemon/tapu_koko/icon.png and b/graphics/pokemon/tapu_koko/icon.png differ diff --git a/graphics/pokemon/tapu_lele/icon.png b/graphics/pokemon/tapu_lele/icon.png index e92e3fd3f189..960eee6e1733 100644 Binary files a/graphics/pokemon/tapu_lele/icon.png and b/graphics/pokemon/tapu_lele/icon.png differ diff --git a/graphics/pokemon/tepig/overworld.png b/graphics/pokemon/tepig/overworld.png index b600bd7e74fb..c78cfebc5bf5 100644 Binary files a/graphics/pokemon/tepig/overworld.png and b/graphics/pokemon/tepig/overworld.png differ diff --git a/graphics/pokemon/togedemaru/icon.png b/graphics/pokemon/togedemaru/icon.png index 2ccf7d60d5f0..8aab88788184 100644 Binary files a/graphics/pokemon/togedemaru/icon.png and b/graphics/pokemon/togedemaru/icon.png differ diff --git a/graphics/pokemon/torracat/icon.png b/graphics/pokemon/torracat/icon.png index b266274f5720..0b5f7a12e0a3 100644 Binary files a/graphics/pokemon/torracat/icon.png and b/graphics/pokemon/torracat/icon.png differ diff --git a/graphics/pokemon/toucannon/icon.png b/graphics/pokemon/toucannon/icon.png index 349c723761ca..ba9740d2983b 100644 Binary files a/graphics/pokemon/toucannon/icon.png and b/graphics/pokemon/toucannon/icon.png differ diff --git a/graphics/pokemon/toxapex/icon.png b/graphics/pokemon/toxapex/icon.png index 5de471d4f382..eed4abe4f4d5 100644 Binary files a/graphics/pokemon/toxapex/icon.png and b/graphics/pokemon/toxapex/icon.png differ diff --git a/graphics/pokemon/trumbeak/icon.png b/graphics/pokemon/trumbeak/icon.png index 7f13c97ae823..708e68f864ec 100644 Binary files a/graphics/pokemon/trumbeak/icon.png and b/graphics/pokemon/trumbeak/icon.png differ diff --git a/graphics/pokemon/tsareena/icon.png b/graphics/pokemon/tsareena/icon.png index f4411956238f..b436e30a219a 100644 Binary files a/graphics/pokemon/tsareena/icon.png and b/graphics/pokemon/tsareena/icon.png differ diff --git a/graphics/pokemon/turtonator/icon.png b/graphics/pokemon/turtonator/icon.png index 4e1b8dbfa18c..2ee4c8952af6 100644 Binary files a/graphics/pokemon/turtonator/icon.png and b/graphics/pokemon/turtonator/icon.png differ diff --git a/graphics/pokemon/tympole/overworld.png b/graphics/pokemon/tympole/overworld.png index 9f9778553c0d..320809dc24bd 100644 Binary files a/graphics/pokemon/tympole/overworld.png and b/graphics/pokemon/tympole/overworld.png differ diff --git a/graphics/pokemon/type_null/icon.png b/graphics/pokemon/type_null/icon.png index e00748e138c2..ac03c60d4e08 100644 Binary files a/graphics/pokemon/type_null/icon.png and b/graphics/pokemon/type_null/icon.png differ diff --git a/graphics/pokemon/vikavolt/icon.png b/graphics/pokemon/vikavolt/icon.png index 7a8f2cff4d46..eff23d50aad9 100644 Binary files a/graphics/pokemon/vikavolt/icon.png and b/graphics/pokemon/vikavolt/icon.png differ diff --git a/graphics/pokemon/vivillon/archipelago/icon.png b/graphics/pokemon/vivillon/archipelago/icon.png index 5dfb32bb6020..82d27575895b 100644 Binary files a/graphics/pokemon/vivillon/archipelago/icon.png and b/graphics/pokemon/vivillon/archipelago/icon.png differ diff --git a/graphics/pokemon/vivillon/continental/icon.png b/graphics/pokemon/vivillon/continental/icon.png index 482c27febab0..725b181c8a46 100644 Binary files a/graphics/pokemon/vivillon/continental/icon.png and b/graphics/pokemon/vivillon/continental/icon.png differ diff --git a/graphics/pokemon/vivillon/elegant/icon.png b/graphics/pokemon/vivillon/elegant/icon.png index fc23f4335ab8..bf2c9a50b695 100644 Binary files a/graphics/pokemon/vivillon/elegant/icon.png and b/graphics/pokemon/vivillon/elegant/icon.png differ diff --git a/graphics/pokemon/vivillon/fancy/icon.png b/graphics/pokemon/vivillon/fancy/icon.png index 2e75d4c340b7..1fa55125e6b2 100644 Binary files a/graphics/pokemon/vivillon/fancy/icon.png and b/graphics/pokemon/vivillon/fancy/icon.png differ diff --git a/graphics/pokemon/vivillon/garden/icon.png b/graphics/pokemon/vivillon/garden/icon.png index bcf56d0ef4f9..e487901f9581 100644 Binary files a/graphics/pokemon/vivillon/garden/icon.png and b/graphics/pokemon/vivillon/garden/icon.png differ diff --git a/graphics/pokemon/vivillon/high_plains/icon.png b/graphics/pokemon/vivillon/high_plains/icon.png index 6e2313e901a1..d68ff6df4a85 100644 Binary files a/graphics/pokemon/vivillon/high_plains/icon.png and b/graphics/pokemon/vivillon/high_plains/icon.png differ diff --git a/graphics/pokemon/vivillon/icon.png b/graphics/pokemon/vivillon/icon.png index b9d27d02eefa..1c5015e07ab5 100644 Binary files a/graphics/pokemon/vivillon/icon.png and b/graphics/pokemon/vivillon/icon.png differ diff --git a/graphics/pokemon/vivillon/jungle/icon.png b/graphics/pokemon/vivillon/jungle/icon.png index e759b4f789eb..9b2923d543d8 100644 Binary files a/graphics/pokemon/vivillon/jungle/icon.png and b/graphics/pokemon/vivillon/jungle/icon.png differ diff --git a/graphics/pokemon/vivillon/marine/icon.png b/graphics/pokemon/vivillon/marine/icon.png index 69b2eab4dec1..b3673e55740d 100644 Binary files a/graphics/pokemon/vivillon/marine/icon.png and b/graphics/pokemon/vivillon/marine/icon.png differ diff --git a/graphics/pokemon/vivillon/modern/icon.png b/graphics/pokemon/vivillon/modern/icon.png index dedc1aa19f97..a28216c157f8 100644 Binary files a/graphics/pokemon/vivillon/modern/icon.png and b/graphics/pokemon/vivillon/modern/icon.png differ diff --git a/graphics/pokemon/vivillon/monsoon/icon.png b/graphics/pokemon/vivillon/monsoon/icon.png index 22fcc286d508..277798f86077 100644 Binary files a/graphics/pokemon/vivillon/monsoon/icon.png and b/graphics/pokemon/vivillon/monsoon/icon.png differ diff --git a/graphics/pokemon/vivillon/ocean/icon.png b/graphics/pokemon/vivillon/ocean/icon.png index 47609a6b591c..764a8cdceec4 100644 Binary files a/graphics/pokemon/vivillon/ocean/icon.png and b/graphics/pokemon/vivillon/ocean/icon.png differ diff --git a/graphics/pokemon/vivillon/poke_ball/icon.png b/graphics/pokemon/vivillon/poke_ball/icon.png index 1ca199b96b8a..7be708eb9530 100644 Binary files a/graphics/pokemon/vivillon/poke_ball/icon.png and b/graphics/pokemon/vivillon/poke_ball/icon.png differ diff --git a/graphics/pokemon/vivillon/polar/icon.png b/graphics/pokemon/vivillon/polar/icon.png index e52390387324..5fc161cca576 100644 Binary files a/graphics/pokemon/vivillon/polar/icon.png and b/graphics/pokemon/vivillon/polar/icon.png differ diff --git a/graphics/pokemon/vivillon/river/icon.png b/graphics/pokemon/vivillon/river/icon.png index 5cb09d29bd5b..475ae4e9d91b 100644 Binary files a/graphics/pokemon/vivillon/river/icon.png and b/graphics/pokemon/vivillon/river/icon.png differ diff --git a/graphics/pokemon/vivillon/sandstorm/icon.png b/graphics/pokemon/vivillon/sandstorm/icon.png index 40822af8664b..b428bf6e9235 100644 Binary files a/graphics/pokemon/vivillon/sandstorm/icon.png and b/graphics/pokemon/vivillon/sandstorm/icon.png differ diff --git a/graphics/pokemon/vivillon/savanna/icon.png b/graphics/pokemon/vivillon/savanna/icon.png index cc12705dd82a..7c58f606e6d3 100644 Binary files a/graphics/pokemon/vivillon/savanna/icon.png and b/graphics/pokemon/vivillon/savanna/icon.png differ diff --git a/graphics/pokemon/vivillon/sun/icon.png b/graphics/pokemon/vivillon/sun/icon.png index 95d3c84e5bed..e14a22faadb8 100644 Binary files a/graphics/pokemon/vivillon/sun/icon.png and b/graphics/pokemon/vivillon/sun/icon.png differ diff --git a/graphics/pokemon/vivillon/tundra/icon.png b/graphics/pokemon/vivillon/tundra/icon.png index fa937ff7ca46..6347455e81ef 100644 Binary files a/graphics/pokemon/vivillon/tundra/icon.png and b/graphics/pokemon/vivillon/tundra/icon.png differ diff --git a/graphics/pokemon/vulpix/alola/icon.png b/graphics/pokemon/vulpix/alola/icon.png index f49562751b54..ccf5bbfcc117 100644 Binary files a/graphics/pokemon/vulpix/alola/icon.png and b/graphics/pokemon/vulpix/alola/icon.png differ diff --git a/graphics/pokemon/watchog/overworld.png b/graphics/pokemon/watchog/overworld.png index f2e9ff47338f..e9184c7375ad 100644 Binary files a/graphics/pokemon/watchog/overworld.png and b/graphics/pokemon/watchog/overworld.png differ diff --git a/graphics/pokemon/watchog/overworld_normal.pal b/graphics/pokemon/watchog/overworld_normal.pal index 3e75b9e987be..0bc0feda6bba 100644 --- a/graphics/pokemon/watchog/overworld_normal.pal +++ b/graphics/pokemon/watchog/overworld_normal.pal @@ -2,8 +2,8 @@ JASC-PAL 0100 16 152 208 160 -90 41 57 -115 49 65 +88 40 56 +112 48 64 0 0 0 148 57 57 47 46 47 @@ -11,7 +11,7 @@ JASC-PAL 218 85 79 230 222 210 212 157 60 -16 16 16 +208 184 144 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/watchog/overworld_shiny.pal b/graphics/pokemon/watchog/overworld_shiny.pal index 0a5ae605c945..dba33393d802 100644 --- a/graphics/pokemon/watchog/overworld_shiny.pal +++ b/graphics/pokemon/watchog/overworld_shiny.pal @@ -3,15 +3,15 @@ JASC-PAL 16 152 208 160 90 41 57 -112 48 86 +112 40 88 0 0 0 -144 56 96 +160 56 104 47 46 47 -152 152 152 -212 118 77 +125 125 125 +240 72 72 193 223 190 -91 169 85 -16 16 16 +120 232 144 +216 192 128 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/whimsicott/overworld.png b/graphics/pokemon/whimsicott/overworld.png index 62057ff6f895..ed1c4db2cb76 100644 Binary files a/graphics/pokemon/whimsicott/overworld.png and b/graphics/pokemon/whimsicott/overworld.png differ diff --git a/graphics/pokemon/whimsicott/overworld_normal.pal b/graphics/pokemon/whimsicott/overworld_normal.pal index c9e2ef3b0095..8e9638c30172 100644 --- a/graphics/pokemon/whimsicott/overworld_normal.pal +++ b/graphics/pokemon/whimsicott/overworld_normal.pal @@ -3,17 +3,17 @@ JASC-PAL 16 152 208 160 168 151 83 -106 84 64 +148 106 65 226 218 202 -41 66 22 -194 178 137 +82 57 41 194 178 137 +106 90 65 12 12 12 41 66 22 66 119 65 237 237 247 -106 84 64 -226 218 202 -0 0 0 -0 0 0 -0 0 0 +70 47 35 +201 189 165 +115 82 65 +230 131 0 +194 114 2 diff --git a/graphics/pokemon/whimsicott/overworld_shiny.pal b/graphics/pokemon/whimsicott/overworld_shiny.pal index 1e09d1a78e6e..ad2e0b45436a 100644 --- a/graphics/pokemon/whimsicott/overworld_shiny.pal +++ b/graphics/pokemon/whimsicott/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -110 94 94 -105 89 68 +152 152 128 +112 96 88 248 240 232 56 50 50 192 192 184 -194 178 137 +120 104 104 9 9 9 -35 86 194 -107 154 170 +40 97 130 +63 151 209 237 237 247 -82 57 41 +56 45 39 230 222 205 -0 0 0 -0 0 0 -0 0 0 +80 64 64 +232 168 0 +176 104 16 diff --git a/graphics/pokemon/wimpod/icon.png b/graphics/pokemon/wimpod/icon.png index 77a80488950d..732b7b9ac078 100644 Binary files a/graphics/pokemon/wimpod/icon.png and b/graphics/pokemon/wimpod/icon.png differ diff --git a/graphics/pokemon/wishiwashi/icon.png b/graphics/pokemon/wishiwashi/icon.png index 0b9df6baf4c0..2e2778650f83 100644 Binary files a/graphics/pokemon/wishiwashi/icon.png and b/graphics/pokemon/wishiwashi/icon.png differ diff --git a/graphics/pokemon/wishiwashi/school/icon.png b/graphics/pokemon/wishiwashi/school/icon.png index 2cf411fd1b84..a756cc555116 100644 Binary files a/graphics/pokemon/wishiwashi/school/icon.png and b/graphics/pokemon/wishiwashi/school/icon.png differ diff --git a/graphics/pokemon/woobat/overworld.png b/graphics/pokemon/woobat/overworld.png index 1d14a5c43d79..18bff8d5c3b0 100644 Binary files a/graphics/pokemon/woobat/overworld.png and b/graphics/pokemon/woobat/overworld.png differ diff --git a/graphics/pokemon/xerneas/icon.png b/graphics/pokemon/xerneas/icon.png index 6d0b56b3b673..8e2a8cc8ff64 100644 Binary files a/graphics/pokemon/xerneas/icon.png and b/graphics/pokemon/xerneas/icon.png differ diff --git a/graphics/pokemon/xurkitree/icon.png b/graphics/pokemon/xurkitree/icon.png index 26cce62f0a8a..4c044631de7c 100644 Binary files a/graphics/pokemon/xurkitree/icon.png and b/graphics/pokemon/xurkitree/icon.png differ diff --git a/graphics/pokemon/yungoos/icon.png b/graphics/pokemon/yungoos/icon.png index 657e0b676432..3001e64f1104 100644 Binary files a/graphics/pokemon/yungoos/icon.png and b/graphics/pokemon/yungoos/icon.png differ diff --git a/graphics/pokemon/zeraora/icon.png b/graphics/pokemon/zeraora/icon.png index b8dadd7ba330..7df134703fc4 100644 Binary files a/graphics/pokemon/zeraora/icon.png and b/graphics/pokemon/zeraora/icon.png differ diff --git a/graphics/pokemon/zygarde/10_percent/icon.png b/graphics/pokemon/zygarde/10_percent/icon.png index c1fd251535ee..ab6354c98570 100644 Binary files a/graphics/pokemon/zygarde/10_percent/icon.png and b/graphics/pokemon/zygarde/10_percent/icon.png differ diff --git a/graphics/pokemon/zygarde/complete/icon.png b/graphics/pokemon/zygarde/complete/icon.png index 454af5dcac37..c7d6c8d01061 100644 Binary files a/graphics/pokemon/zygarde/complete/icon.png and b/graphics/pokemon/zygarde/complete/icon.png differ diff --git a/include/battle.h b/include/battle.h index c8f014ca3684..5d6281cb319a 100644 --- a/include/battle.h +++ b/include/battle.h @@ -250,6 +250,7 @@ struct SpecialStatus u8 emergencyExited:1; u8 afterYou:1; u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects. + u8 distortedTypeMatchups:1; }; struct SideTimer @@ -823,12 +824,12 @@ struct BattleStruct u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT]; u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values. u8 boosterEnergyActivates; - u8 distortedTypeMatchups; u8 categoryOverride; // for Z-Moves and Max Moves u8 commandingDondozo; - u16 commanderActive[NUM_BATTLE_SIDES]; + u16 commanderActive[MAX_BATTLERS_COUNT]; u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side u8 redCardActivates:1; + u8 padding:7; u8 usedEjectItem; u8 usedMicleBerry; u8 monCausingSleepClause[NUM_BATTLE_SIDES]; // Stores which pokemon on a given side is causing Sleep Clause to be active as the mon's index in the party diff --git a/include/battle_message.h b/include/battle_message.h index 0b4570e389fa..7d000d289fda 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -10,6 +10,7 @@ max(POKEMON_NAME_LENGTH + 1, \ ABILITY_NAME_LENGTH + 1))) #define BATTLE_MSG_MAX_WIDTH 208 +#define BATTLE_MSG_MAX_LINES 2 // for 0xFD #define B_TXT_BUFF1 0x0 diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 766c2532f61c..fd84b814b64e 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -65,7 +65,9 @@ extern const u8 BattleScript_OverworldTerrain[]; extern const u8 BattleScript_SideStatusWoreOff[]; extern const u8 BattleScript_SafeguardProtected[]; extern const u8 BattleScript_SafeguardEnds[]; -extern const u8 BattleScript_LeechSeedTurnDrain[]; +extern const u8 BattleScript_LeechSeedTurnDrainLiquidOoze[]; +extern const u8 BattleScript_LeechSeedTurnDrainHealBlock[]; +extern const u8 BattleScript_LeechSeedTurnDrainRecovery[]; extern const u8 BattleScript_BideStoringEnergy[]; extern const u8 BattleScript_BideAttack[]; extern const u8 BattleScript_BideNoEnergyToAttack[]; @@ -439,7 +441,6 @@ extern const u8 BattleScript_AttackWeakenedByStrongWinds[]; extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[]; extern const u8 BattleScript_BlockedByPrimalWeatherRet[]; extern const u8 BattleScript_PrimalReversion[]; -extern const u8 BattleScript_PrimalReversionRestoreAttacker[]; extern const u8 BattleScript_HyperspaceFuryRemoveProtect[]; extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[]; extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace[]; @@ -563,6 +564,7 @@ extern const u8 BattleScript_MoveBlockedByDynamax[]; // Battle move scripts extern const u8 BattleScript_EffectSleep[]; extern const u8 BattleScript_EffectAbsorb[]; +extern const u8 BattleScript_EffectAbsorbLiquidOoze[]; extern const u8 BattleScript_EffectExplosion[]; extern const u8 BattleScript_EffectDreamEater[]; extern const u8 BattleScript_EffectMirrorMove[]; diff --git a/include/battle_util.h b/include/battle_util.h index fd9164fbfe5f..395cbf28e35d 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -99,6 +99,7 @@ enum CANCELLER_SKY_DROP, CANCELLER_ASLEEP, CANCELLER_FROZEN, + CANCELLER_OBEDIENCE, CANCELLER_TRUANT, CANCELLER_RECHARGE, CANCELLER_FLINCH, @@ -299,6 +300,7 @@ bool32 CanGetFrostbite(u32 battler); bool32 CanBeConfused(u32 battler); bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag); u32 GetBattlerAffectionHearts(u32 battler); +void TryToRevertMimicryAndFlags(void); u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc); bool32 ChangeTypeBasedOnTerrain(u32 battler); void RemoveConfusionStatus(u32 battler); diff --git a/include/config/battle.h b/include/config/battle.h index de29a2f03b9d..43da40301067 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -6,7 +6,7 @@ #define B_CRIT_MULTIPLIER GEN_LATEST // In Gen6+, critical hits multiply damage by 1.5 instead of 2. #define B_PARALYSIS_SPEED GEN_LATEST // In Gen7+, Speed is decreased by 50% instead of 75%. #define B_CONFUSION_SELF_DMG_CHANCE GEN_LATEST // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%. -#define B_MULTI_HIT_CHANCE GEN_LATEST // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values. +#define B_MULTI_HIT_CHANCE GEN_LATEST // In Gen5+, multi-hit moves have different %. See SetRandomMultiHitCounter for values. #define B_WHITEOUT_MONEY GEN_LATEST // In Gen4+, the amount of money lost by losing a battle is determined by the amount of badges earned. Previously, it would cut the current money by half. (While this change was also in FRLG, for the sake of simplicity, setting this to GEN_3 will result in RSE behavior.) #define B_LIGHT_BALL_ATTACK_BOOST GEN_LATEST // In Gen4+, Light Ball doubles the power of physical moves in addition to special moves. #define B_SANDSTORM_SPDEF_BOOST GEN_LATEST // In Gen4+, Sandstorm weather multiplies the Sp. Defense of Rock-type Pokémon by x1.5. diff --git a/include/constants/battle.h b/include/constants/battle.h index d337559f1bff..ed19a72d9ce6 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -507,7 +507,7 @@ #define MOVE_TARGET_FOES_AND_ALLY (1 << 5) #define MOVE_TARGET_OPPONENTS_FIELD (1 << 6) #define MOVE_TARGET_ALLY (1 << 7) -#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER) +#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER) // No functionality for status moves // For the second argument of GetMoveTarget, when no target override is needed #define NO_TARGET_OVERRIDE 0 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 6b162dc4871e..050a20d933f7 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -263,6 +263,7 @@ enum MoveEndEffects { MOVEEND_SUM_DAMAGE, MOVEEND_PROTECT_LIKE_EFFECT, + MOVEEND_ABSORB, MOVEEND_RAGE, MOVEEND_SYNCHRONIZE_TARGET, MOVEEND_ABILITIES, @@ -288,9 +289,9 @@ enum MoveEndEffects MOVEEND_RECOIL, MOVEEND_ITEM_EFFECTS_ATTACKER, MOVEEND_MAGICIAN, // Occurs after final multi-hit strike, and after other items/abilities would activate + MOVEEND_RED_CARD, // Red Card triggers before Eject Pack MOVEEND_EJECT_ITEMS, MOVEEND_WHITE_HERB, - MOVEEND_RED_CARD, MOVEEND_LIFEORB_SHELLBELL, // Includes shell bell, throat spray, etc MOVEEND_CHANGED_ITEMS, MOVEEND_PICKPOCKET, diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 327a502e22db..6b3a5ace78db 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -1,9 +1,9 @@ #ifndef GUARD_CONSTANTS_EXPANSION_H #define GUARD_CONSTANTS_EXPANSION_H -// Last version: 1.9.3 +// Last version: 1.10.1 #define EXPANSION_VERSION_MAJOR 1 -#define EXPANSION_VERSION_MINOR 10 +#define EXPANSION_VERSION_MINOR 11 #define EXPANSION_VERSION_PATCH 0 // FALSE if this this version of Expansion is not a tagged commit, i.e. diff --git a/include/constants/form_change_types.h b/include/constants/form_change_types.h index 74bc16cf2f5c..79a8a4cee7bb 100644 --- a/include/constants/form_change_types.h +++ b/include/constants/form_change_types.h @@ -134,4 +134,8 @@ // param1: amount of days #define FORM_CHANGE_DAYS_PASSED 23 +// Form change for Aegislash +#define FORM_CHANGE_BATTLE_ATTACK 24 +#define FORM_CHANGE_BATTLE_KINGS_SHIELD 25 + #endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H diff --git a/include/line_break.h b/include/line_break.h new file mode 100644 index 000000000000..c423c9bf405b --- /dev/null +++ b/include/line_break.h @@ -0,0 +1,33 @@ +#ifndef GUARD_LINE_BREAK_H +#define GUARD_LINE_BREAK_H + +#define BADNESS_UNFILLED 1 // Badness added per pixel diff from max width +#define BADNESS_JAGGED 1 // Badness added per pixel diff from longest, squared per line +#define BADNESS_RUNT 100 // Badness added if there's a runt +#define BADNESS_OVERFLOW 100 // Badness added per pixel overflow, squared per line (not used) +#define BADNESS_WIDE_SPACE 1 // Badness added per extra pixel width (not used) +#define MAX_SPACE_WIDTH 5 + +struct StringWord { + u32 startIndex:16; + u32 length:8; + u32 width:8; +}; + +struct StringLine { + struct StringWord *words; + u16 numWords; + u8 spaceWidth; + u8 extraSpaceWidth; +}; + +void StripLineBreaks(u8 *src); +void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId); +void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId); + +bool32 IsWordSplittingChar(const u8 *src, u32 index); +u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth); +void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str); +bool32 StringHasManualBreaks(u8 *src); + +#endif // GUARD_LINE_BREAK_H diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index ee87e09ec1f6..21c738de0182 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3518,6 +3518,7 @@ u32 AI_WhoStrikesFirstPartyMon(u32 battlerAtk, u32 battlerDef, struct BattlePoke SetBattlerAiData(battlerAtk, AI_DATA); u32 aiMonFaster = AI_IsFaster(battlerAtk, battlerDef, moveConsidered); FreeRestoreBattleMons(savedBattleMons); + SetBattlerAiData(battlerAtk, AI_DATA); return aiMonFaster; } diff --git a/src/battle_anim_flying.c b/src/battle_anim_flying.c index 42c99740d351..8b613ad67714 100644 --- a/src/battle_anim_flying.c +++ b/src/battle_anim_flying.c @@ -363,7 +363,6 @@ static void AnimEllipticalGustCentered(struct Sprite *sprite) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else InitSpritePosToAnimTarget(sprite, FALSE); - sprite->y += 20; sprite->data[1] = 191; sprite->callback = AnimEllipticalGust_Step; diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c index 04fd111a842b..240e43b713fe 100644 --- a/src/battle_anim_mon_movement.c +++ b/src/battle_anim_mon_movement.c @@ -15,8 +15,10 @@ static void ReverseHorizontalLungeDirection(struct Sprite *sprite); static void DoVerticalDip(struct Sprite *sprite); static void ReverseVerticalDipDirection(struct Sprite *sprite); static void SlideMonToOriginalPos(struct Sprite *sprite); +static void SlideMonToOriginalPosPartner(struct Sprite *sprite); static void SlideMonToOriginalPos_Step(struct Sprite *sprite); static void SlideMonToOffset(struct Sprite *sprite); +static void SlideMonToOffsetPartner(struct Sprite *sprite); static void SlideMonToOffsetAndBack(struct Sprite *sprite); static void SlideMonToOffsetAndBack_End(struct Sprite *sprite); static void AnimTask_WindUpLunge_Step1(u8 taskId); @@ -63,6 +65,17 @@ const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate = .callback = SlideMonToOriginalPos, }; +const struct SpriteTemplate gSlideMonToOriginalPosPartnerSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SlideMonToOriginalPosPartner, +}; + const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate = { .tileTag = 0, @@ -74,6 +87,17 @@ const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate = .callback = SlideMonToOffset, }; +const struct SpriteTemplate gSlideMonToOffsetPartnerSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SlideMonToOffsetPartner, +}; + const struct SpriteTemplate gSlideMonToOffsetAndBackSpriteTemplate = { .tileTag = 0, @@ -487,7 +511,41 @@ static void ReverseVerticalDipDirection(struct Sprite *sprite) // arg 2: duration static void SlideMonToOriginalPos(struct Sprite *sprite) { - u32 monSpriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + u32 monSpriteId; + if (!gBattleAnimArgs[0]) + monSpriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + else + monSpriteId = gBattlerSpriteIds[gBattleAnimTarget]; + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gSprites[monSpriteId].x + gSprites[monSpriteId].x2; + sprite->data[2] = gSprites[monSpriteId].x; + sprite->data[3] = gSprites[monSpriteId].y + gSprites[monSpriteId].y2; + sprite->data[4] = gSprites[monSpriteId].y; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = gSprites[monSpriteId].x2; + sprite->data[6] = gSprites[monSpriteId].y2; + sprite->invisible = TRUE; + + if (gBattleAnimArgs[1] == 1) + sprite->data[2] = 0; + else if (gBattleAnimArgs[1] == 2) + sprite->data[1] = 0; + + sprite->data[7] = gBattleAnimArgs[1]; + sprite->data[7] |= monSpriteId << 8; + sprite->callback = SlideMonToOriginalPos_Step; +} + +static void SlideMonToOriginalPosPartner(struct Sprite *sprite) +{ + u32 monSpriteId; + if (!gBattleAnimArgs[0]) + monSpriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]; + else + monSpriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]; sprite->data[0] = gBattleAnimArgs[2]; sprite->data[1] = gSprites[monSpriteId].x + gSprites[monSpriteId].x2; @@ -550,9 +608,48 @@ static void SlideMonToOriginalPos_Step(struct Sprite *sprite) // arg 4: duration static void SlideMonToOffset(struct Sprite *sprite) { - u8 monSpriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + u8 battler; + u8 monSpriteId; + if (!gBattleAnimArgs[0]) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + monSpriteId = gBattlerSpriteIds[battler]; + if (GetBattlerSide(battler) != B_SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gSprites[monSpriteId].x; + sprite->data[2] = gSprites[monSpriteId].x + gBattleAnimArgs[1]; + sprite->data[3] = gSprites[monSpriteId].y; + sprite->data[4] = gSprites[monSpriteId].y + gBattleAnimArgs[2]; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = monSpriteId; + sprite->invisible = TRUE; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = TranslateSpriteLinearByIdFixedPoint; +} + +static void SlideMonToOffsetPartner(struct Sprite *sprite) +{ + u8 battler; + u8 monSpriteId; + if (!gBattleAnimArgs[0]) + battler = BATTLE_PARTNER(gBattleAnimAttacker); + else + battler = BATTLE_PARTNER(gBattleAnimTarget); - if (GetBattlerSide(gBattleAnimArgs[0]) != B_SIDE_PLAYER) + monSpriteId = gBattlerSpriteIds[battler]; + if (GetBattlerSide(battler) != B_SIDE_PLAYER) { gBattleAnimArgs[1] = -gBattleAnimArgs[1]; if (gBattleAnimArgs[3] == 1) diff --git a/src/battle_anim_rock.c b/src/battle_anim_rock.c index 354fb21014e6..ec7bc535df96 100644 --- a/src/battle_anim_rock.c +++ b/src/battle_anim_rock.c @@ -478,14 +478,15 @@ void AnimRockFragment(struct Sprite *sprite) // Swirls particle in vortex. Used for moves like Fire Spin or Sand Tomb void AnimParticleInVortex(struct Sprite *sprite) { - if (IsDoubleBattle() //got a little lazy here will fix later - && (gAnimMoveIndex == MOVE_BLEAKWIND_STORM + if (IsDoubleBattle() + && (gAnimMoveIndex == MOVE_BLEAKWIND_STORM || gAnimMoveIndex == MOVE_SANDSEAR_STORM || gAnimMoveIndex == MOVE_SPRINGTIDE_STORM || gAnimMoveIndex == MOVE_WILDBOLT_STORM)) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else - InitSpritePosToAnimTarget(sprite, FALSE); + InitSpritePosToAnimBattler(gBattleAnimArgs[6], sprite, FALSE); + sprite->data[0] = gBattleAnimArgs[3]; sprite->data[1] = gBattleAnimArgs[2]; sprite->data[2] = gBattleAnimArgs[4]; diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index ef12589681a3..b6ffd67b75ae 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -648,6 +648,22 @@ static void OpponentHandleChooseItem(u32 battler) OpponentBufferExecCompleted(battler); } +static inline bool32 IsAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler) +{ + return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON + && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) + && CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle; +} + +static inline bool32 IsDoubleAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler) +{ + return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON + && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) + && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2) + && CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle + && CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) != pokemonInBattle; +} + static void OpponentHandleChoosePokemon(u32 battler) { s32 chosenMonId; @@ -680,20 +696,14 @@ static void OpponentHandleChoosePokemon(u32 battler) GetAIPartyIndexes(battler, &firstId, &lastId); for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--) { - if (!IsValidForBattle(&gEnemyParty[chosenMonId])) - continue; - if (chosenMonId == gBattlerPartyIndexes[battler1] + if (!IsValidForBattle(&gEnemyParty[chosenMonId]) + || chosenMonId == gBattlerPartyIndexes[battler1] || chosenMonId == gBattlerPartyIndexes[battler2]) continue; - if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON) - && ((chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) || CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle)) - continue; - if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON) - && (((chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) || (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2)) - || (CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle || CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) == pokemonInBattle))) - continue; - // mon is valid - break; + + if (!IsAcePokemon(chosenMonId, pokemonInBattle, battler) + && !IsDoubleAcePokemon(chosenMonId, pokemonInBattle, battler)) + break; } } gBattleStruct->monToSwitchIntoId[battler] = chosenMonId; @@ -709,7 +719,6 @@ static void OpponentHandleChoosePokemon(u32 battler) #endif // TESTING BtlController_EmitChosenMonReturnValue(battler, BUFFER_B, chosenMonId, NULL); OpponentBufferExecCompleted(battler); - } static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 87b1cd5ca4a5..33969994873f 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -31,6 +31,7 @@ #include "text.h" #include "util.h" #include "window.h" +#include "line_break.h" #include "constants/battle_anim.h" #include "constants/battle_move_effects.h" #include "constants/battle_partner.h" @@ -2044,6 +2045,7 @@ static void PlayerHandleChooseAction(u32 battler) ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo); + BreakStringAutomatic(gDisplayedStringBattle, WindowWidthPx(B_WIN_ACTION_PROMPT), 2, FONT_NORMAL); if (B_SHOW_PARTNER_TARGET && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && IsBattlerAlive(B_POSITION_PLAYER_RIGHT)) { diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c index b85157f24668..932ce47fd938 100644 --- a/src/battle_controller_safari.c +++ b/src/battle_controller_safari.c @@ -20,6 +20,7 @@ #include "text.h" #include "util.h" #include "window.h" +#include "line_break.h" #include "constants/battle_anim.h" #include "constants/songs.h" #include "constants/trainers.h" @@ -298,6 +299,7 @@ static void SafariHandleChooseAction(u32 battler) ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2); + BreakStringAutomatic(gDisplayedStringBattle, WindowWidthPx(B_WIN_ACTION_PROMPT), 2, FONT_NORMAL); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); } diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 4fd89fb66440..79995b0f16eb 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -280,7 +280,10 @@ static u16 GetTypeBasedMaxMove(u32 battler, u32 type) // Returns the appropriate Max Move or G-Max Move for a battler to use. u16 GetMaxMove(u32 battler, u32 baseMove) { - u32 move = baseMove; + u32 moveType; + SetTypeBeforeUsingMove(baseMove, battler); + moveType = GetMoveType(baseMove); + if (baseMove == MOVE_NONE) // for move display { return MOVE_NONE; @@ -291,18 +294,12 @@ u16 GetMaxMove(u32 battler, u32 baseMove) } else if (gMovesInfo[baseMove].category == DAMAGE_CATEGORY_STATUS) { - move = MOVE_MAX_GUARD; - } - else if (gBattleStruct->dynamicMoveType) - { - move = GetTypeBasedMaxMove(battler, gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK); + return MOVE_MAX_GUARD; } else { - move = GetTypeBasedMaxMove(battler, gMovesInfo[baseMove].type); + return GetTypeBasedMaxMove(battler, moveType); } - - return move; } // First value is for Fighting, Poison and Multi-Attack. The second is for everything else. diff --git a/src/battle_message.c b/src/battle_message.c index e12e1465ffaf..46256accdd81 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -22,6 +22,7 @@ #include "text.h" #include "trainer_hill.h" #include "window.h" +#include "line_break.h" #include "constants/abilities.h" #include "constants/battle_dome.h" #include "constants/battle_string_ids.h" @@ -165,6 +166,11 @@ const u8 gText_drastically[] = _("drastically "); const u8 gText_severely[] = _("severely "); static const u8 sText_TerrainReturnedToNormal[] = _("The terrain returned to normal!"); // Unused +// Remove these when done testing +static const u8 sTest_TempTestText1[] = _("This is a text for testing stuff."); +static const u8 sTest_TempTestText2[] = _("This is a text for testing stuff that should be two lines."); +static const u8 sTest_TempTestText3[] = _("This is a text for testing stuff that should be three lines so it has to have some extra text."); + const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { [STRINGID_TRAINER1LOSETEXT] = COMPOUND_STRING("{B_TRAINER1_LOSE_TEXT}"), @@ -192,30 +198,30 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = #else [STRINGID_PLAYERWHITEOUT2] = COMPOUND_STRING("You were overwhelmed by your defeat!{PAUSE_UNTIL_PRESS}"), #endif - [STRINGID_PREVENTSESCAPE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents escape with {B_SCR_ACTIVE_ABILITY}!\p"), + [STRINGID_PREVENTSESCAPE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} prevents escape with {B_SCR_ACTIVE_ABILITY}!\p"), [STRINGID_HITXTIMES] = COMPOUND_STRING("The Pokémon was hit {B_BUFF1} time(s)!"), //SV has dynamic plural here [STRINGID_PKMNFELLASLEEP] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} fell asleep!"), - [STRINGID_PKMNMADESLEEP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} made {B_EFF_NAME_WITH_PREFIX2} sleep!"), //not in gen 5+, ability popup + [STRINGID_PKMNMADESLEEP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} made {B_EFF_NAME_WITH_PREFIX2} sleep!"), //not in gen 5+, ability popup [STRINGID_PKMNALREADYASLEEP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already asleep!"), [STRINGID_PKMNALREADYASLEEP2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is already asleep!"), [STRINGID_PKMNWASNTAFFECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} wasn't affected!"), //not in gen 5+, ability popup [STRINGID_PKMNWASPOISONED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned!"), - [STRINGID_PKMNPOISONEDBY] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned by {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), //not in gen 5+, ability popup + [STRINGID_PKMNPOISONEDBY] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned by {B_SCR_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), //not in gen 5+, ability popup [STRINGID_PKMNHURTBYPOISON] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its poisoning!"), [STRINGID_PKMNALREADYPOISONED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already poisoned!"), [STRINGID_PKMNBADLYPOISONED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was badly poisoned!"), [STRINGID_PKMNENERGYDRAINED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} had its energy drained!"), [STRINGID_PKMNWASBURNED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was burned!"), - [STRINGID_PKMNBURNEDBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} burned {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup + [STRINGID_PKMNBURNEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} burned {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup [STRINGID_PKMNHURTBYBURN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its burn!"), [STRINGID_PKMNWASFROZEN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was frozen solid!"), - [STRINGID_PKMNFROZENBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} froze {B_EFF_NAME_WITH_PREFIX2} solid!"), //not in gen 5+, ability popup + [STRINGID_PKMNFROZENBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} froze {B_EFF_NAME_WITH_PREFIX2} solid!"), //not in gen 5+, ability popup [STRINGID_PKMNISFROZEN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is frozen solid!"), [STRINGID_PKMNWASDEFROSTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} thawed out!"), [STRINGID_PKMNWASDEFROSTED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} thawed out!"), [STRINGID_PKMNWASDEFROSTEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} melted the ice!"), [STRINGID_PKMNWASPARALYZED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} is paralyzed, so it may be unable to move!"), - [STRINGID_PKMNWASPARALYZEDBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} paralyzed {B_EFF_NAME_WITH_PREFIX2}, so it may be unable to move!"), //not in gen 5+, ability popup + [STRINGID_PKMNWASPARALYZEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} paralyzed {B_EFF_NAME_WITH_PREFIX2}, so it may be unable to move!"), //not in gen 5+, ability popup [STRINGID_PKMNISPARALYZED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} couldn't move because it's paralyzed!"), [STRINGID_PKMNISALREADYPARALYZED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already paralyzed!"), [STRINGID_PKMNHEALEDPARALYSIS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was cured of paralysis!"), @@ -229,7 +235,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNWASCONFUSED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} became confused!"), [STRINGID_PKMNALREADYCONFUSED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already confused!"), [STRINGID_PKMNFELLINLOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fell in love!"), - [STRINGID_PKMNINLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is in love with {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"), + [STRINGID_PKMNINLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is in love with {B_SCR_NAME_WITH_PREFIX2}!"), [STRINGID_PKMNIMMOBILIZEDBYLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is immobilized by love!"), [STRINGID_PKMNBLOWNAWAY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was blown away!"), //unused [STRINGID_PKMNCHANGEDTYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} transformed into the {B_BUFF1} type!"), @@ -239,7 +245,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNRAISEDSPDEF] = COMPOUND_STRING("Light Screen made {B_ATK_TEAM2} team stronger against special moves!"), [STRINGID_PKMNRAISEDDEF] = COMPOUND_STRING("Reflect made {B_ATK_TEAM2} team stronger against physical moves!"), [STRINGID_PKMNCOVEREDBYVEIL] = COMPOUND_STRING("{B_ATK_TEAM1} team cloaked itself in a mystical veil!"), - [STRINGID_PKMNUSEDSAFEGUARD] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected by Safeguard!"), + [STRINGID_PKMNUSEDSAFEGUARD] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is protected by Safeguard!"), [STRINGID_PKMNSAFEGUARDEXPIRED] = COMPOUND_STRING("{B_ATK_TEAM1} team is no longer protected by Safeguard!"), [STRINGID_PKMNWENTTOSLEEP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} went to sleep!"), //not in gen 5+ [STRINGID_PKMNSLEPTHEALTHY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} slept and restored its HP!"), @@ -257,7 +263,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNFREEDFROM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was freed from {B_BUFF1}!"), [STRINGID_PKMNCRASHED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} kept going and crashed!"), [STRINGID_PKMNSHROUDEDINMIST] = gText_PkmnShroudedInMist, - [STRINGID_PKMNPROTECTEDBYMIST] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected by the mist!"), + [STRINGID_PKMNPROTECTEDBYMIST] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is protected by the mist!"), [STRINGID_PKMNGETTINGPUMPED] = gText_PkmnGettingPumped, [STRINGID_PKMNHITWITHRECOIL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was damaged by the recoil!"), [STRINGID_PKMNPROTECTEDITSELF2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} protected itself!"), @@ -268,7 +274,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNSAPPEDBYLEECHSEED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s health is sapped by Leech Seed!"), [STRINGID_PKMNFASTASLEEP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is fast asleep."), [STRINGID_PKMNWOKEUP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} woke up!"), - [STRINGID_PKMNUPROARKEPTAWAKE] = COMPOUND_STRING("But the uproar kept {B_SCR_ACTIVE_NAME_WITH_PREFIX2} awake!"), + [STRINGID_PKMNUPROARKEPTAWAKE] = COMPOUND_STRING("But the uproar kept {B_SCR_NAME_WITH_PREFIX2} awake!"), [STRINGID_PKMNWOKEUPINUPROAR] = COMPOUND_STRING("The uproar woke {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_PKMNCAUSEDUPROAR] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} caused an uproar!"), [STRINGID_PKMNMAKINGUPROAR] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is making an uproar!"), @@ -308,7 +314,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNLAIDCURSE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cut its own HP and put a curse on {B_DEF_NAME_WITH_PREFIX2}!"), [STRINGID_PKMNAFFLICTEDBYCURSE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is afflicted by the curse!"), [STRINGID_SPIKESSCATTERED] = COMPOUND_STRING("Spikes were scattered on the ground all around {B_DEF_TEAM2} team!"), - [STRINGID_PKMNHURTBYSPIKES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was hurt by the spikes!"), + [STRINGID_PKMNHURTBYSPIKES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was hurt by the spikes!"), [STRINGID_PKMNIDENTIFIED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was identified!"), [STRINGID_PKMNPERISHCOUNTFELL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s perish count fell to {B_BUFF1}!"), [STRINGID_PKMNBRACEDITSELF] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} braced itself!"), @@ -351,9 +357,9 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNSHROUDEDITSELF] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} shrouded itself with Magic Coat!"), [STRINGID_PKMNMOVEBOUNCED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} bounced the {B_CURRENT_MOVE} back!"), [STRINGID_PKMNWAITSFORTARGET] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} waits for a target to make a move!"), - [STRINGID_PKMNSNATCHEDMOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} snatched {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s move!"), - [STRINGID_PKMNMADEITRAIN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it rain!"), //not in gen 5+, ability popup - [STRINGID_PKMNRAISEDSPEED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its Speed!"), //not in gen 5+, ability popup + [STRINGID_PKMNSNATCHEDMOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} snatched {B_SCR_NAME_WITH_PREFIX2}'s move!"), + [STRINGID_PKMNMADEITRAIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it rain!"), //not in gen 5+, ability popup + [STRINGID_PKMNRAISEDSPEED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its Speed!"), //not in gen 5+, ability popup [STRINGID_PKMNPROTECTEDBY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was protected by {B_DEF_ABILITY}!"), //not in gen 5+, ability popup [STRINGID_PKMNPREVENTSUSAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents {B_ATK_NAME_WITH_PREFIX2} from using {B_CURRENT_MOVE}!"), //I don't see this in SV text [STRINGID_PKMNRESTOREDHPUSING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} restored HP using its {B_DEF_ABILITY}!"), //not in gen 5+, ability popup @@ -364,8 +370,8 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNPREVENTSCONFUSIONWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents confusion!"), //not in gen 5+, ability popup [STRINGID_PKMNRAISEDFIREPOWERWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} raised the power of Fire-type moves!"), //not in gen 5+, ability popup [STRINGID_PKMNANCHORSITSELFWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} anchors itself with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup - [STRINGID_PKMNCUTSATTACKWITH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cuts {B_DEF_NAME_WITH_PREFIX2}'s Attack!"), //not in gen 5+, ability popup - [STRINGID_PKMNPREVENTSSTATLOSSWITH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents stat loss!"), //not in gen 5+, ability popup + [STRINGID_PKMNCUTSATTACKWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cuts {B_DEF_NAME_WITH_PREFIX2}'s Attack!"), //not in gen 5+, ability popup + [STRINGID_PKMNPREVENTSSTATLOSSWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents stat loss!"), //not in gen 5+, ability popup [STRINGID_PKMNHURTSWITH] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), [STRINGID_PKMNTRACED] = COMPOUND_STRING("It traced {B_BUFF1}'s {B_BUFF2}!"), [STRINGID_STATSHARPLY] = gText_StatSharply, @@ -450,30 +456,30 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNIGNOREDX] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} completely ignored the {B_BUFF1}!"), //safari [STRINGID_THREWPOKEBLOCKATPKMN] = COMPOUND_STRING("{B_PLAYER_NAME} threw a {POKEBLOCK} at the {B_OPPONENT_MON1_NAME}!"), //safari [STRINGID_OUTOFSAFARIBALLS] = COMPOUND_STRING("{PLAY_SE SE_DING_DONG}ANNOUNCER: You're out of Safari Balls! Game over!\p"), //safari - [STRINGID_PKMNSITEMCUREDPARALYSIS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its paralysis!"), - [STRINGID_PKMNSITEMCUREDPOISON] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its poison!"), - [STRINGID_PKMNSITEMHEALEDBURN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its burn!"), - [STRINGID_PKMNSITEMDEFROSTEDIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} defrosted it!"), - [STRINGID_PKMNSITEMWOKEIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} woke it up!"), - [STRINGID_PKMNSITEMSNAPPEDOUT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} snapped it out of its confusion!"), - [STRINGID_PKMNSITEMCUREDPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its {B_BUFF1} problem!"), - [STRINGID_PKMNSITEMRESTOREDHEALTH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored its health using its {B_LAST_ITEM}!"), - [STRINGID_PKMNSITEMRESTOREDPP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored PP to its move {B_BUFF1} using its {B_LAST_ITEM}!"), - [STRINGID_PKMNSITEMRESTOREDSTATUS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} returned its stats to normal using its {B_LAST_ITEM}!"), - [STRINGID_PKMNSITEMRESTOREDHPALITTLE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored a little HP using its {B_LAST_ITEM}!"), + [STRINGID_PKMNSITEMCUREDPARALYSIS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its paralysis!"), + [STRINGID_PKMNSITEMCUREDPOISON] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its poison!"), + [STRINGID_PKMNSITEMHEALEDBURN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its burn!"), + [STRINGID_PKMNSITEMDEFROSTEDIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} defrosted it!"), + [STRINGID_PKMNSITEMWOKEIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} woke it up!"), + [STRINGID_PKMNSITEMSNAPPEDOUT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} snapped it out of its confusion!"), + [STRINGID_PKMNSITEMCUREDPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its {B_BUFF1} problem!"), + [STRINGID_PKMNSITEMRESTOREDHEALTH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored its health using its {B_LAST_ITEM}!"), + [STRINGID_PKMNSITEMRESTOREDPP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored PP to its move {B_BUFF1} using its {B_LAST_ITEM}!"), + [STRINGID_PKMNSITEMRESTOREDSTATUS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} returned its stats to normal using its {B_LAST_ITEM}!"), + [STRINGID_PKMNSITEMRESTOREDHPALITTLE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored a little HP using its {B_LAST_ITEM}!"), [STRINGID_ITEMALLOWSONLYYMOVE] = COMPOUND_STRING("{B_LAST_ITEM} only allows the use of {B_CURRENT_MOVE}!\p"), [STRINGID_PKMNHUNGONWITHX] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} hung on using its {B_LAST_ITEM}!"), [STRINGID_EMPTYSTRING3] = gText_EmptyString3, [STRINGID_PKMNSXPREVENTSBURNS] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} prevents burns!"), //not in gen 5+, ability popup [STRINGID_PKMNSXBLOCKSY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup [STRINGID_PKMNSXRESTOREDHPALITTLE2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} restored its HP a little!"), //not in gen 5+, ability popup - [STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup - [STRINGID_PKMNSXPREVENTSYLOSS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_BUFF1} loss!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXPREVENTSYLOSS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_BUFF1} loss!"), //not in gen 5+, ability popup [STRINGID_PKMNSXINFATUATEDY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} infatuated {B_ATK_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup [STRINGID_PKMNSXMADEYINEFFECTIVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} ineffective!"), //not in gen 5+, ability popup - [STRINGID_PKMNSXCUREDYPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXCUREDYPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup [STRINGID_ITSUCKEDLIQUIDOOZE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} sucked up the liquid ooze!"), - [STRINGID_PKMNTRANSFORMED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!"), + [STRINGID_PKMNTRANSFORMED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} transformed!"), [STRINGID_ELECTRICITYWEAKENED] = COMPOUND_STRING("Electricity's power was weakened!"), [STRINGID_FIREWEAKENED] = COMPOUND_STRING("Fire's power was weakened!"), [STRINGID_PKMNHIDUNDERWATER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} hid underwater!"), @@ -483,14 +489,14 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PLAYERDEFEATEDTRAINER1] = sText_PlayerDefeatedLinkTrainerTrainer1, [STRINGID_SOOTHINGAROMA] = COMPOUND_STRING("A soothing aroma wafted through the area!"), [STRINGID_ITEMSCANTBEUSEDNOW] = COMPOUND_STRING("Items can't be used now.{PAUSE 64}"), //not in gen 5+, i think - [STRINGID_FORXCOMMAYZ] = COMPOUND_STRING("For {B_SCR_ACTIVE_NAME_WITH_PREFIX2}, {B_LAST_ITEM} {B_BUFF1}"), //not in gen 5+, expansion doesn't use anymore - [STRINGID_USINGITEMSTATOFPKMNROSE] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_ACTIVE_NAME_WITH_PREFIX2} {B_BUFF2}"), //todo: update this, will require code changes - [STRINGID_PKMNUSEDXTOGETPUMPED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used the {B_LAST_ITEM} to get pumped!"), + [STRINGID_FORXCOMMAYZ] = COMPOUND_STRING("For {B_SCR_NAME_WITH_PREFIX2}, {B_LAST_ITEM} {B_BUFF1}"), //not in gen 5+, expansion doesn't use anymore + [STRINGID_USINGITEMSTATOFPKMNROSE] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_NAME_WITH_PREFIX2} {B_BUFF2}"), //todo: update this, will require code changes + [STRINGID_PKMNUSEDXTOGETPUMPED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used the {B_LAST_ITEM} to get pumped!"), [STRINGID_PKMNSXMADEYUSELESS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} useless!"), //not in gen 5+, ability popup [STRINGID_PKMNTRAPPEDBYSANDTOMB] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} became trapped by the quicksand!"), [STRINGID_EMPTYSTRING4] = COMPOUND_STRING(""), [STRINGID_ABOOSTED] = COMPOUND_STRING(" a boosted"), - [STRINGID_PKMNSXINTENSIFIEDSUN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} intensified the sun's rays!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXINTENSIFIEDSUN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} intensified the sun's rays!"), //not in gen 5+, ability popup [STRINGID_PKMNMAKESGROUNDMISS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} makes Ground-type moves miss with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup [STRINGID_YOUTHROWABALLNOWRIGHT] = COMPOUND_STRING("You throw a Ball now, right? I… I'll do my best!"), [STRINGID_PKMNSXTOOKATTACK] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} took the attack!"), //In gen 5+ but without naming the ability @@ -500,35 +506,35 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNFLEDUSINGITS] = COMPOUND_STRING("{PLAY_SE SE_FLEE}{B_ATK_NAME_WITH_PREFIX} fled using its {B_LAST_ITEM}!\p"), [STRINGID_PKMNFLEDUSING] = COMPOUND_STRING("{PLAY_SE SE_FLEE}{B_ATK_NAME_WITH_PREFIX} fled using {B_ATK_ABILITY}!\p"), //not in gen 5+ [STRINGID_PKMNWASDRAGGEDOUT] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was dragged out!\p"), - [STRINGID_PREVENTEDFROMWORKING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevented {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s {B_BUFF1} from working!"), //unused - [STRINGID_PKMNSITEMNORMALIZEDSTATUS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} normalized its status!"), + [STRINGID_PREVENTEDFROMWORKING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevented {B_SCR_NAME_WITH_PREFIX2}'s {B_BUFF1} from working!"), //unused + [STRINGID_PKMNSITEMNORMALIZEDSTATUS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} normalized its status!"), [STRINGID_TRAINER1USEDITEM] = COMPOUND_STRING("{B_ATK_TRAINER_NAME_WITH_CLASS} used {B_LAST_ITEM}!"), [STRINGID_BOXISFULL] = COMPOUND_STRING("The Box is full! You can't catch any more!\p"), [STRINGID_PKMNAVOIDEDATTACK] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} avoided the attack!"), - [STRINGID_PKMNSXMADEITINEFFECTIVE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it ineffective!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXMADEITINEFFECTIVE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it ineffective!"), //not in gen 5+, ability popup [STRINGID_PKMNSXPREVENTSFLINCHING] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} prevents flinching!"), //not in gen 5+, ability popup [STRINGID_PKMNALREADYHASBURN] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already burned!"), [STRINGID_STATSWONTDECREASE2] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s stats won't go any lower!"), - [STRINGID_PKMNSXBLOCKSY2] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXBLOCKSY2] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup [STRINGID_PKMNSXWOREOFF] = COMPOUND_STRING("{B_ATK_TEAM1} team's {B_BUFF1} wore off!"), [STRINGID_PKMNRAISEDDEFALITTLE] = COMPOUND_STRING("{B_ATK_PREFIX1}'s {B_CURRENT_MOVE} raised DEFENSE a little!"), //expansion doesn't use anymore [STRINGID_PKMNRAISEDSPDEFALITTLE] = COMPOUND_STRING("{B_ATK_PREFIX1}'s {B_CURRENT_MOVE} raised SP. DEF a little!"), //expansion doesn't use anymore [STRINGID_THEWALLSHATTERED] = COMPOUND_STRING("The wall shattered!"), //not in gen5+, uses "your teams light screen wore off!" etc instead [STRINGID_PKMNSXPREVENTSYSZ] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"), - [STRINGID_PKMNSXCUREDITSYPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXCUREDITSYPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup [STRINGID_ATTACKERCANTESCAPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can't escape!"), [STRINGID_PKMNOBTAINEDX] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} obtained {B_BUFF1}."), [STRINGID_PKMNOBTAINEDX2] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."), [STRINGID_PKMNOBTAINEDXYOBTAINEDZ] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} obtained {B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."), [STRINGID_BUTNOEFFECT] = COMPOUND_STRING("But it had no effect!"), - [STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} had no effect on {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup + [STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} had no effect on {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup [STRINGID_TWOENEMIESDEFEATED] = sText_TwoInGameTrainersDefeated, [STRINGID_TRAINER2LOSETEXT] = COMPOUND_STRING("{B_TRAINER2_LOSE_TEXT}"), [STRINGID_PKMNINCAPABLEOFPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} appears incapable of using its power!"), - [STRINGID_GLINTAPPEARSINEYE] = COMPOUND_STRING("A glint appears in {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s eyes!"), - [STRINGID_PKMNGETTINGINTOPOSITION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is getting into position!"), - [STRINGID_PKMNBEGANGROWLINGDEEPLY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!"), - [STRINGID_PKMNEAGERFORMORE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!"), + [STRINGID_GLINTAPPEARSINEYE] = COMPOUND_STRING("A glint appears in {B_SCR_NAME_WITH_PREFIX2}'s eyes!"), + [STRINGID_PKMNGETTINGINTOPOSITION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is getting into position!"), + [STRINGID_PKMNBEGANGROWLINGDEEPLY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} began growling deeply!"), + [STRINGID_PKMNEAGERFORMORE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is eager for more!"), [STRINGID_DEFEATEDOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} defeated the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"), [STRINGID_LOSTTOOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} lost to the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"), [STRINGID_TIEDOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} tied the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"), @@ -584,7 +590,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_KINDOFFER] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} took the kind offer!"), [STRINGID_RESETSTARGETSSTATLEVELS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s stat changes were removed!"), [STRINGID_EMPTYSTRING6] = sText_EmptyString4, - [STRINGID_ALLYSWITCHPOSITION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} and {B_SCR_ACTIVE_NAME_WITH_PREFIX2} switched places!"), + [STRINGID_ALLYSWITCHPOSITION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} and {B_SCR_NAME_WITH_PREFIX2} switched places!"), [STRINGID_RESTORETARGETSHEALTH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s HP was restored!"), [STRINGID_TOOKPJMNINTOTHESKY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} took {B_DEF_NAME_WITH_PREFIX2} into the sky!"), [STRINGID_FREEDFROMSKYDROP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was freed from the Sky Drop!"), @@ -613,15 +619,15 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_ATTACKERABILITYSTATRAISE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} raised its {B_BUFF1}!"), [STRINGID_POISONHEALHPUP] = COMPOUND_STRING("The poisoning healed {B_ATK_NAME_WITH_PREFIX2} a little bit!"), //don't think this message is displayed anymore [STRINGID_BADDREAMSDMG] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is tormented!"), - [STRINGID_MOLDBREAKERENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} breaks the mold!"), - [STRINGID_TERAVOLTENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a bursting aura!"), - [STRINGID_TURBOBLAZEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a blazing aura!"), - [STRINGID_SLOWSTARTENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is slow to get going!"), + [STRINGID_MOLDBREAKERENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} breaks the mold!"), + [STRINGID_TERAVOLTENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a bursting aura!"), + [STRINGID_TURBOBLAZEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a blazing aura!"), + [STRINGID_SLOWSTARTENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is slow to get going!"), [STRINGID_SLOWSTARTEND] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} finally got its act together!"), [STRINGID_SOLARPOWERHPDROP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} takes its toll!"), //don't think this message is displayed anymore [STRINGID_AFTERMATHDMG] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt!"), - [STRINGID_ANTICIPATIONACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shuddered!"), - [STRINGID_FOREWARNACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_ACTIVE_NAME_WITH_PREFIX2} to {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), + [STRINGID_ANTICIPATIONACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} shuddered!"), + [STRINGID_FOREWARNACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_NAME_WITH_PREFIX2} to {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), [STRINGID_ICEBODYHPGAIN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} healed it a little bit!"), //don't think this message is displayed anymore [STRINGID_SNOWWARNINGHAIL] = COMPOUND_STRING("It started to hail!"), [STRINGID_FRISKACTIVATES] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} frisked {B_DEF_NAME_WITH_PREFIX2} and found its {B_LAST_ITEM}!"), @@ -630,11 +636,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_LASTABILITYRAISEDSTAT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} raised its {B_BUFF1}!"), [STRINGID_MAGICBOUNCEACTIVATES] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} bounced the {B_ATK_NAME_WITH_PREFIX2} back!"), [STRINGID_PROTEANTYPECHANGE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} transformed it into the {B_BUFF1} type!"), - [STRINGID_SYMBIOSISITEMPASS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} passed its {B_LAST_ITEM} to {B_ATK_NAME_WITH_PREFIX2} through {B_LAST_ABILITY}!"), - [STRINGID_STEALTHROCKDMG] = COMPOUND_STRING("Pointed stones dug into {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"), + [STRINGID_SYMBIOSISITEMPASS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} passed its {B_LAST_ITEM} to {B_ATK_NAME_WITH_PREFIX2} through {B_LAST_ABILITY}!"), + [STRINGID_STEALTHROCKDMG] = COMPOUND_STRING("Pointed stones dug into {B_SCR_NAME_WITH_PREFIX2}!"), [STRINGID_TOXICSPIKESABSORBED] = COMPOUND_STRING("The poison spikes disappeared from the ground around {B_ATK_TEAM2} team!"), - [STRINGID_TOXICSPIKESPOISONED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was poisoned!"), - [STRINGID_STICKYWEBSWITCHIN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was caught in a sticky web!"), + [STRINGID_TOXICSPIKESPOISONED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was poisoned!"), + [STRINGID_STICKYWEBSWITCHIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was caught in a sticky web!"), [STRINGID_HEALINGWISHCAMETRUE] = COMPOUND_STRING("The healing wish came true for {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_HEALINGWISHHEALED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} regained health!"), [STRINGID_LUNARDANCECAMETRUE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in mystical moonlight!"), @@ -666,7 +672,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_SEVERELY] = gText_severely, [STRINGID_INFESTATION] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} has been afflicted with an infestation by {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_NOEFFECTONTARGET] = COMPOUND_STRING("It won't have any effect on {B_DEF_NAME_WITH_PREFIX2}!"), - [STRINGID_BURSTINGFLAMESHIT] = COMPOUND_STRING("The bursting flames hit {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"), + [STRINGID_BURSTINGFLAMESHIT] = COMPOUND_STRING("The bursting flames hit {B_SCR_NAME_WITH_PREFIX2}!"), [STRINGID_BESTOWITEMGIVING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} received {B_LAST_ITEM} from {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_THIRDTYPEADDED] = COMPOUND_STRING("{B_BUFF1} type was added to {B_DEF_NAME_WITH_PREFIX2}!"), [STRINGID_FELLFORFEINT] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fell for the feint!"), @@ -692,46 +698,46 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_GEMACTIVATES] = COMPOUND_STRING("The {B_LAST_ITEM} strengthened {B_ATK_NAME_WITH_PREFIX2}'s power!"), [STRINGID_BERRYDMGREDUCES] = COMPOUND_STRING("The {B_LAST_ITEM} weakened the damage to {B_DEF_NAME_WITH_PREFIX2}!"), [STRINGID_TARGETATEITEM] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} ate its {B_LAST_ITEM}!"), - [STRINGID_AIRBALLOONFLOAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} floats in the air with its Air Balloon!"), + [STRINGID_AIRBALLOONFLOAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} floats in the air with its Air Balloon!"), [STRINGID_AIRBALLOONPOP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s Air Balloon popped!"), [STRINGID_INCINERATEBURN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM} was burnt up!"), [STRINGID_BUGBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole and ate its target's {B_LAST_ITEM}!"), [STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s illusion wore off!"), [STRINGID_ATTACKERCUREDTARGETSTATUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured {B_DEF_NAME_WITH_PREFIX2}'s problem!"), [STRINGID_ATTACKERLOSTFIRETYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} burned itself out!"), - [STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} cured {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s problem!"), - [STRINGID_SCRIPTINGABILITYSTATRAISE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"), - [STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} was taken over!"), + [STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} cured {B_SCR_NAME_WITH_PREFIX2}'s problem!"), + [STRINGID_SCRIPTINGABILITYSTATRAISE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"), + [STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} was taken over!"), [STRINGID_PKNMABSORBINGPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is absorbing power!"), [STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("No one will be able to run away during the next turn!"), - [STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"), + [STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"), [STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in a freezing light!"), [STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_DEF_NAME_WITH_PREFIX2} prevents its stats from being lowered!"), [STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}'s fervent wish has reached {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_AIRLOCKACTIVATES] = COMPOUND_STRING("The effects of the weather disappeared."), - [STRINGID_PRESSUREENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is exerting its pressure!"), - [STRINGID_DARKAURAENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a dark aura!"), - [STRINGID_FAIRYAURAENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a fairy aura!"), - [STRINGID_AURABREAKENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} reversed all other Pokémon's auras!"), - [STRINGID_COMATOSEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is drowsing!"), + [STRINGID_PRESSUREENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is exerting its pressure!"), + [STRINGID_DARKAURAENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a dark aura!"), + [STRINGID_FAIRYAURAENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a fairy aura!"), + [STRINGID_AURABREAKENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} reversed all other Pokémon's auras!"), + [STRINGID_COMATOSEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is drowsing!"), [STRINGID_SCREENCLEANERENTERS] = COMPOUND_STRING("All screens on the field were cleansed!"), - [STRINGID_FETCHEDPOKEBALL] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} found a {B_LAST_ITEM}!"), - [STRINGID_BATTLERABILITYRAISEDSTAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"), + [STRINGID_FETCHEDPOKEBALL] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} found a {B_LAST_ITEM}!"), + [STRINGID_BATTLERABILITYRAISEDSTAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"), [STRINGID_ASANDSTORMKICKEDUP] = COMPOUND_STRING("A sandstorm kicked up!"), [STRINGID_PKMNSWILLPERISHIN3TURNS] = COMPOUND_STRING("Both Pokémon will perish in three turns!"), //don't think this message is displayed anymore [STRINGID_ABILITYRAISEDSTATDRASTICALLY] = COMPOUND_STRING("{B_DEF_ABILITY} raised {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1} drastically!"), [STRINGID_AURAFLAREDTOLIFE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s aura flared to life!"), - [STRINGID_ASONEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!"), + [STRINGID_ASONEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} has two Abilities!"), [STRINGID_CURIOUSMEDICINEENTERS] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s stat changes were removed!"), [STRINGID_CANACTFASTERTHANKSTO] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can act faster than normal, thanks to its {B_BUFF1}!"), - [STRINGID_MICLEBERRYACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its next move using {B_LAST_ITEM}!"), - [STRINGID_PKMNSHOOKOFFTHETAUNT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off the taunt!"), - [STRINGID_PKMNGOTOVERITSINFATUATION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over its infatuation!"), + [STRINGID_MICLEBERRYACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted the accuracy of its next move using {B_LAST_ITEM}!"), + [STRINGID_PKMNSHOOKOFFTHETAUNT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} shook off the taunt!"), + [STRINGID_PKMNGOTOVERITSINFATUATION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} got over its infatuation!"), [STRINGID_ITEMCANNOTBEREMOVED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s item cannot be removed!"), [STRINGID_STICKYBARBTRANSFER] = COMPOUND_STRING("The {B_LAST_ITEM} attached itself to {B_ATK_NAME_WITH_PREFIX2}!"), [STRINGID_PKMNBURNHEALED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s burn was cured!"), - [STRINGID_REDCARDACTIVATE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} held up its Red Card against {B_ATK_NAME_WITH_PREFIX2}!"), - [STRINGID_EJECTBUTTONACTIVATE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is switched out with the {B_LAST_ITEM}!"), + [STRINGID_REDCARDACTIVATE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} held up its Red Card against {B_ATK_NAME_WITH_PREFIX2}!"), + [STRINGID_EJECTBUTTONACTIVATE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is switched out with the {B_LAST_ITEM}!"), [STRINGID_ATKGOTOVERINFATUATION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} got over its infatuation!"), [STRINGID_TORMENTEDNOMORE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is no longer tormented!"), [STRINGID_HEALBLOCKEDNOMORE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is cured of its heal block!"), @@ -750,7 +756,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_MYSTERIOUSAIRCURRENTBLOWSON] = COMPOUND_STRING("The mysterious strong winds blow on regardless!"), [STRINGID_ATTACKWEAKENEDBSTRONGWINDS] = COMPOUND_STRING("The mysterious strong winds weakened the attack!"), [STRINGID_STUFFCHEEKSCANTSELECT] = COMPOUND_STRING("It can't use the move because it doesn't have a Berry!\p"), - [STRINGID_PKMNREVERTEDTOPRIMAL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s Primal Reversion! It reverted to its primal state!"), + [STRINGID_PKMNREVERTEDTOPRIMAL] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s Primal Reversion! It reverted to its primal state!"), [STRINGID_BUTPOKEMONCANTUSETHEMOVE] = COMPOUND_STRING("But {B_ATK_NAME_WITH_PREFIX2} can't use the move!"), [STRINGID_BUTHOOPACANTUSEIT] = COMPOUND_STRING("But {B_ATK_NAME_WITH_PREFIX2} can't use it the way it is now!"), [STRINGID_BROKETHROUGHPROTECTION] = COMPOUND_STRING("It broke through {B_DEF_NAME_WITH_PREFIX2}'s protection!"), @@ -758,7 +764,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_SWAPPEDABILITIES] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} swapped Abilities with its target!"), [STRINGID_PASTELVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is protected by a pastel veil!"), [STRINGID_PASTELVEILENTERS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was cured of its poisoning!"), - [STRINGID_BATTLERTYPECHANGEDTO] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s type changed to {B_BUFF1}!"), + [STRINGID_BATTLERTYPECHANGEDTO] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s type changed to {B_BUFF1}!"), [STRINGID_BOTHCANNOLONGERESCAPE] = COMPOUND_STRING("Neither Pokémon can run away!"), [STRINGID_CANTESCAPEDUETOUSEDMOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can no longer escape because it used No Retreat!"), [STRINGID_PKMNBECAMEWEAKERTOFIRE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} became weaker to fire!"), @@ -776,12 +782,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PLAYERPAIDPRIZEMONEY] = COMPOUND_STRING("You gave ¥{B_BUFF1} to the winner…\pYou were overwhelmed by your defeat!{PAUSE_UNTIL_PRESS}"), [STRINGID_ZPOWERSURROUNDS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} surrounded itself with its Z-Power!"), [STRINGID_ZMOVEUNLEASHED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} unleashes its full-force Z-Move!"), - [STRINGID_ZMOVERESETSSTATS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} returned its decreased stats to normal using its Z-Power!"), - [STRINGID_ZMOVEALLSTATSUP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"), - [STRINGID_ZMOVEZBOOSTCRIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its critical-hit ratio using its Z-Power!"), - [STRINGID_ZMOVERESTOREHP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored its HP using its Z-Power!"), - [STRINGID_ZMOVESTATUP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"), - [STRINGID_ZMOVEHPTRAP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s HP was restored by the Z-Power!"), + [STRINGID_ZMOVERESETSSTATS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} returned its decreased stats to normal using its Z-Power!"), + [STRINGID_ZMOVEALLSTATSUP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"), + [STRINGID_ZMOVEZBOOSTCRIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its critical-hit ratio using its Z-Power!"), + [STRINGID_ZMOVERESTOREHP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored its HP using its Z-Power!"), + [STRINGID_ZMOVESTATUP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"), + [STRINGID_ZMOVEHPTRAP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s HP was restored by the Z-Power!"), [STRINGID_ATTACKEREXPELLEDTHEPOISON] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} managed to expel the poison so you wouldn't worry!"), [STRINGID_ATTACKERSHOOKITSELFAWAKE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} shook itself awake so you wouldn't worry!"), [STRINGID_ATTACKERBROKETHROUGHPARALYSIS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} gathered all its energy to break through its paralysis so you wouldn't worry!"), @@ -791,12 +797,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_ATTACKERLOSTELECTRICTYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} used up all its electricity!"), [STRINGID_ATTACKERSWITCHEDSTATWITHTARGET] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} switched {B_BUFF1} with its target!"), [STRINGID_BEINGHITCHARGEDPKMNWITHPOWER] = COMPOUND_STRING("Being hit by {B_CURRENT_MOVE} charged {B_DEF_NAME_WITH_PREFIX2} with power!"), - [STRINGID_SUNLIGHTACTIVATEDABILITY] = COMPOUND_STRING("The harsh sunlight activated {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s Protosynthesis!"), - [STRINGID_STATWASHEIGHTENED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"), - [STRINGID_ELECTRICTERRAINACTIVATEDABILITY] = COMPOUND_STRING("The Electric Terrain activated {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s Quark Drive!"), - [STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} weakened the {B_BUFF1} of all surrounding Pokémon!\p"), - [STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} gained strength from the fallen!"), - [STRINGID_PKMNSABILITYPREVENTSABILITY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"), //not in gen 5+, ability popup + [STRINGID_SUNLIGHTACTIVATEDABILITY] = COMPOUND_STRING("The harsh sunlight activated {B_SCR_NAME_WITH_PREFIX2}'s Protosynthesis!"), + [STRINGID_STATWASHEIGHTENED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"), + [STRINGID_ELECTRICTERRAINACTIVATEDABILITY] = COMPOUND_STRING("The Electric Terrain activated {B_SCR_NAME_WITH_PREFIX2}'s Quark Drive!"), + [STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} weakened the {B_BUFF1} of all surrounding Pokémon!\p"), + [STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} gained strength from the fallen!"), + [STRINGID_PKMNSABILITYPREVENTSABILITY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"), //not in gen 5+, ability popup [STRINGID_PREPARESHELLTRAP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} set a shell trap!"), [STRINGID_SHELLTRAPDIDNTWORK] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s shell trap didn't work!"), [STRINGID_SPIKESDISAPPEAREDFROMTEAM] = COMPOUND_STRING("The spikes disappeared from the ground around {B_ATK_TEAM2} team!"), @@ -812,12 +818,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_THUNDERCAGETRAPPED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} trapped {B_DEF_NAME_WITH_PREFIX2}!"), [STRINGID_PKMNHURTBYFROSTBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its frostbite!"), [STRINGID_PKMNGOTFROSTBITE] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} got frostbite!"), - [STRINGID_PKMNSITEMHEALEDFROSTBITE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its frostbite!"), + [STRINGID_PKMNSITEMHEALEDFROSTBITE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its frostbite!"), [STRINGID_ATTACKERHEALEDITSFROSTBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured its frostbite through sheer determination so you wouldn't worry!"), [STRINGID_PKMNFROSTBITEHEALED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s frostbite was cured!"), [STRINGID_PKMNFROSTBITEHEALED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s frostbite was cured!"), [STRINGID_PKMNFROSTBITEHEALEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} cured its frostbite!"), - [STRINGID_MIRRORHERBCOPIED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used its Mirror Herb to mirror its opponent's stat changes!"), + [STRINGID_MIRRORHERBCOPIED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used its Mirror Herb to mirror its opponent's stat changes!"), [STRINGID_STARTEDSNOW] = COMPOUND_STRING("It started to snow!"), [STRINGID_SNOWCONTINUES] = COMPOUND_STRING("Snow continues to fall."), //not in gen 5+ (lol) [STRINGID_SNOWSTOPPED] = COMPOUND_STRING("The snow stopped."), @@ -843,7 +849,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_TEAMSURROUNDEDBYROCKS] = COMPOUND_STRING("{B_DEF_TEAM1} Pokémon became surrounded by rocks!"), [STRINGID_PKMNHURTBYROCKSTHROWN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is hurt by rocks thrown out by G-Max Volcalith!"), [STRINGID_MOVEBLOCKEDBYDYNAMAX] = COMPOUND_STRING("The move was blocked by the power of Dynamax!"), - [STRINGID_ZEROTOHEROTRANSFORMATION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} underwent a heroic transformation!"), + [STRINGID_ZEROTOHEROTRANSFORMATION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} underwent a heroic transformation!"), [STRINGID_THETWOMOVESBECOMEONE] = COMPOUND_STRING("The two moves have become one! It's a combined move!{PAUSE 16}"), [STRINGID_ARAINBOWAPPEAREDONSIDE] = COMPOUND_STRING("A rainbow appeared in the sky on {B_ATK_TEAM2} team's side!"), [STRINGID_THERAINBOWDISAPPEARED] = COMPOUND_STRING("The rainbow on {B_ATK_TEAM2} team's side disappeared!"), @@ -866,13 +872,13 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_BIZARREAREACREATED] = COMPOUND_STRING("A bizarre area was created in which Defense and Sp. Def stats are swapped!"), [STRINGID_TIDYINGUPCOMPLETE] = COMPOUND_STRING("Tidying up complete!"), [STRINGID_PKMNTERASTALLIZEDINTO] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} terastallized into the {B_BUFF1} type!"), - [STRINGID_BOOSTERENERGYACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used its {B_LAST_ITEM} to activate {B_SCR_ACTIVE_ABILITY}!"), + [STRINGID_BOOSTERENERGYACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used its {B_LAST_ITEM} to activate {B_SCR_ACTIVE_ABILITY}!"), [STRINGID_FOGCREPTUP] = COMPOUND_STRING("Fog crept up as thick as soup!"), [STRINGID_FOGISDEEP] = COMPOUND_STRING("The fog is deep…"), [STRINGID_FOGLIFTED] = COMPOUND_STRING("The fog lifted."), [STRINGID_PKMNMADESHELLGLEAM] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} made its shell gleam! It's distorting type matchups!"), [STRINGID_FICKLEBEAMDOUBLED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is going all out for this attack!"), - [STRINGID_COMMANDERACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was swallowed by Dondozo and became Dondozo's commander!"), + [STRINGID_COMMANDERACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was swallowed by Dondozo and became Dondozo's commander!"), [STRINGID_POKEFLUTECATCHY] = COMPOUND_STRING("{B_PLAYER_NAME} played the {B_LAST_ITEM}.\pNow, that's a catchy tune!"), [STRINGID_POKEFLUTE] = COMPOUND_STRING("{B_PLAYER_NAME} played the {B_LAST_ITEM}."), [STRINGID_MONHEARINGFLUTEAWOKE] = COMPOUND_STRING("The Pokémon hearing the flute awoke!"), @@ -1403,8 +1409,8 @@ const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!"); const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p"); const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p"); const u8 gText_EllipsisQuestionMark[] = _("……?\p"); -const u8 gText_WhatWillPkmnDo[] = _("What will\n{B_BUFF1} do?"); -const u8 gText_WhatWillPkmnDo2[] = _("What will\n{B_PLAYER_NAME} do?"); +const u8 gText_WhatWillPkmnDo[] = _("What will {B_BUFF1} do?"); +const u8 gText_WhatWillPkmnDo2[] = _("What will {B_PLAYER_NAME} do?"); const u8 gText_WhatWillWallyDo[] = _("What will\nWALLY do?"); const u8 gText_LinkStandby[] = _("{PAUSE 16}Link standby…"); const u8 gText_BattleMenu[] = _("Battle{CLEAR_TO 56}Bag\nPokémon{CLEAR_TO 56}Run"); @@ -2422,8 +2428,7 @@ static void GetBattlerNick(u32 battler, u8 *dst) } \ } \ GetBattlerNick(battler, text); \ - toCpy = text; \ - dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize); + toCpy = text; #define HANDLE_NICKNAME_STRING_LOWERCASE(battler) \ if (GetBattlerSide(battler) != B_SIDE_PLAYER) \ @@ -2440,8 +2445,7 @@ static void GetBattlerNick(u32 battler, u8 *dst) } \ } \ GetBattlerNick(battler, text); \ - toCpy = text; \ - dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize); + toCpy = text; static const u8 *BattleStringGetOpponentNameByTrainerId(u16 trainerId, u8 *text, u8 multiplayerId, u8 battler) { @@ -2590,17 +2594,10 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) { u32 dstID = 0; // if they used dstID, why not use srcID as well? const u8 *toCpy = NULL; - u32 lastValidSkip = 0; - u32 toCpyWidth = 0; - u32 dstWidth = 0; - // 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 *textStart = &text[0]; u8 multiplayerId; u8 fontId = FONT_NORMAL; - s16 letterSpacing = 0; - u32 lineNum = 1; - u32 displayedLineNums = 1; if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) multiplayerId = gRecordedBattleMultiplayerId; @@ -2618,11 +2615,14 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) while (*src != EOS) { toCpy = NULL; - dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize); if (*src == PLACEHOLDER_BEGIN) { src++; + u32 classLength = 0; + u32 nameLength = 0; + const u8 *classString; + const u8 *nameString; switch (*src) { case B_TXT_BUFF1: @@ -2801,9 +2801,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) break; case B_TXT_TRAINER1_NAME_WITH_CLASS: // trainer1 name with trainer class toCpy = textStart; - textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A)); - textStart = StringAppend(textStart, gText_Space2); - textStart = StringAppend(textStart, BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))); + classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A); + while (classString[classLength] != EOS) + { + textStart[classLength] = classString[classLength]; + classLength++; + } + textStart[classLength] = CHAR_SPACE; + textStart += classLength + 1; + nameString = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)); + if (nameString != textStart) + { + while (nameString[nameLength] != EOS) + { + textStart[nameLength] = nameString[nameLength]; + nameLength++; + } + textStart[nameLength] = EOS; + } break; case B_TXT_LINK_PLAYER_NAME: // link player name toCpy = gLinkPlayers[multiplayerId].name; @@ -2923,9 +2938,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) break; case B_TXT_TRAINER2_NAME_WITH_CLASS: toCpy = textStart; - textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B)); - textStart = StringAppend(textStart, gText_Space2); - textStart = StringAppend(textStart, BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))); + classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B); + while (classString[classLength] != EOS) + { + textStart[classLength] = classString[classLength]; + classLength++; + } + textStart[classLength] = CHAR_SPACE; + textStart += classLength + 1; + nameString = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)); + if (nameString != textStart) + { + while (nameString[nameLength] != EOS) + { + textStart[nameLength] = nameString[nameLength]; + nameLength++; + } + textStart[nameLength] = EOS; + } break; case B_TXT_TRAINER2_LOSE_TEXT: if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) @@ -2963,9 +2993,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) break; case B_TXT_PARTNER_NAME_WITH_CLASS: toCpy = textStart; - textStart = StringCopy(textStart, gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name); - textStart = StringAppend(textStart, gText_Space2); - textStart = StringAppend(textStart, BattleStringGetPlayerName(textStart, GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))); + classString = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name; + while (classString[classLength] != EOS) + { + textStart[classLength] = classString[classLength]; + classLength++; + } + textStart[classLength] = CHAR_SPACE; + textStart += classLength + 1; + nameString = BattleStringGetPlayerName(textStart, GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)); + if (nameString != textStart) + { + while (nameString[nameLength] != EOS) + { + textStart[nameLength] = nameString[nameLength]; + nameLength++; + } + textStart[nameLength] = EOS; + } break; case B_TXT_ATK_TRAINER_NAME: toCpy = BattleStringGetTrainerName(text, multiplayerId, gBattlerAttacker); @@ -2996,24 +3041,42 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) } else { + classString = NULL; switch (GetBattlerPosition(gBattlerAttacker)) { case B_POSITION_PLAYER_RIGHT: if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - textStart = StringCopy(textStart, gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name); + classString = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name; break; case B_POSITION_OPPONENT_LEFT: - textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A)); + classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A); break; case B_POSITION_OPPONENT_RIGHT: if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT) - textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B)); + classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B); else - textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A)); + classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A); break; } - textStart = StringAppend(textStart, gText_Space2); - textStart = StringAppend(textStart, BattleStringGetTrainerName(textStart, multiplayerId, gBattlerAttacker)); + classLength = 0; + nameLength = 0; + while (classString[classLength] != EOS) + { + textStart[classLength] = classString[classLength]; + classLength++; + } + textStart[classLength] = CHAR_SPACE; + textStart += 1 + classLength; + nameString = BattleStringGetTrainerName(textStart, multiplayerId, gBattlerAttacker); + if (nameString != textStart) + { + while (nameString[nameLength] != EOS) + { + textStart[nameLength] = nameString[nameLength]; + nameLength++; + } + textStart[nameLength] = EOS; + } } break; case B_TXT_ATK_TEAM1: @@ -3056,18 +3119,6 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) if (toCpy != NULL) { - toCpyWidth = GetStringLineWidth(fontId, toCpy, letterSpacing, 1, dstSize); - - if (dstWidth + toCpyWidth > BATTLE_MSG_MAX_WIDTH) - { - dst[lastValidSkip] = displayedLineNums == 1 ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL; - dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize); - if (displayedLineNums == 1) - displayedLineNums++; - else - displayedLineNums = 1; - lineNum++; - } while (*toCpy != EOS) { dst[dstID] = *toCpy; @@ -3087,31 +3138,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) } else { - toCpyWidth = GetGlyphWidth(*src, FALSE, fontId); dst[dstID] = *src; - if (dstWidth + toCpyWidth > BATTLE_MSG_MAX_WIDTH) - { - dst[lastValidSkip] = displayedLineNums == 1 ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL; - if (displayedLineNums == 1) - displayedLineNums++; - else - displayedLineNums = 1; - lineNum++; - dstWidth = 0; - } - switch (*src) - { - case CHAR_PROMPT_CLEAR: - case CHAR_PROMPT_SCROLL: - displayedLineNums = 1; - case CHAR_NEWLINE: - lineNum++; - dstWidth = 0; - //fallthrough - case CHAR_SPACE: - lastValidSkip = dstID; - break; - } dstID++; } src++; @@ -3120,6 +3147,8 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) dst[dstID] = *src; dstID++; + BreakStringAutomatic(dst, BATTLE_MSG_MAX_WIDTH, BATTLE_MSG_MAX_WIDTH, fontId); + return dstID; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ea3022ae24ef..70acb753dfda 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -479,7 +479,7 @@ static void Cmd_statbuffchange(void); static void Cmd_normalisebuffs(void); static void Cmd_setbide(void); static void Cmd_twoturnmoveschargestringandanimation(void); -static void Cmd_setmultihitcounter(void); +static void Cmd_unused_0x8d(void); static void Cmd_initmultihitstring(void); static void Cmd_forcerandomswitch(void); static void Cmd_tryconversiontypechange(void); @@ -738,7 +738,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_normalisebuffs, //0x8A Cmd_setbide, //0x8B Cmd_twoturnmoveschargestringandanimation, //0x8C - Cmd_setmultihitcounter, //0x8D + Cmd_unused_0x8d, //0x8D Cmd_initmultihitstring, //0x8E Cmd_forcerandomswitch, //0x8F Cmd_tryconversiontypechange, //0x90 @@ -1125,7 +1125,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move) return FALSE; } -// TODO: Convert this to a proper FORM_CHANGE type. static bool32 TryAegiFormChange(void) { // Only Aegislash with Stance Change can transform, transformed mons cannot. @@ -1140,12 +1139,12 @@ static bool32 TryAegiFormChange(void) case SPECIES_AEGISLASH_SHIELD: // Shield -> Blade if (IS_MOVE_STATUS(gCurrentMove)) return FALSE; - gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE; + TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_ATTACK); break; case SPECIES_AEGISLASH_BLADE: // Blade -> Shield if (gCurrentMove != MOVE_KINGS_SHIELD) return FALSE; - gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_SHIELD; + TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_KINGS_SHIELD); break; } @@ -1171,7 +1170,7 @@ bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType) bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef) { - if (!(gBattleStruct->distortedTypeMatchups & (1u << battlerDef)) + if (!gSpecialStatuses[battlerDef].distortedTypeMatchups && GetBattlerAbility(battlerDef) == ABILITY_TERA_SHELL && gBattleMons[battlerDef].species == SPECIES_TERAPAGOS_TERASTAL && !IS_MOVE_STATUS(move) @@ -1288,55 +1287,6 @@ static void Cmd_attackcanceler(void) gHitMarker &= ~HITMARKER_ALLOW_NO_PP; - if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - switch (gBattleStruct->obedienceResult) - { - case OBEYS: - break; - case DISOBEYS_LOAFS: - // Randomly select, then print a disobedient string - // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE - gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS); - gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; - gMoveResultFlags |= MOVE_RESULT_MISSED; - return; - case DISOBEYS_HITS_SELF: - gBattlerTarget = gBattlerAttacker; - struct DamageCalculationData damageCalcData; - damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; - damageCalcData.move = MOVE_NONE; - damageCalcData.moveType = TYPE_MYSTERY; - damageCalcData.isCrit = FALSE; - damageCalcData.randomFactor = FALSE; - damageCalcData.updateFlags = TRUE; - gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, 40); - gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gHitMarker |= HITMARKER_OBEYS; - return; - case DISOBEYS_FALL_ASLEEP: - if (FlagGet(B_FLAG_SLEEP_CLAUSE)) - gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; - gMoveResultFlags |= MOVE_RESULT_MISSED; - return; - case DISOBEYS_WHILE_ASLEEP: - gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep; - gMoveResultFlags |= MOVE_RESULT_MISSED; - return; - case DISOBEYS_RANDOM_MOVE: - gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - SetAtkCancellerForCalledMove(); - gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; - gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gHitMarker |= HITMARKER_DISOBEDIENT_MOVE; - gHitMarker |= HITMARKER_OBEYS; - return; - } - } - - gHitMarker |= HITMARKER_OBEYS; // Check if no available target present on the field or if Sky Battles ban the move if ((NoTargetPresent(gBattlerAttacker, gCurrentMove) && (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))) @@ -1784,8 +1734,6 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u if (!RandomPercentage(RNG_ACCURACY, accuracy)) { gMoveResultFlags |= MOVE_RESULT_MISSED; - if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY) - gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS && !recalcDragonDarts // So we don't jump back and forth between targets @@ -1895,7 +1843,7 @@ static void Cmd_ppreduce(void) if (ShouldTeraShellDistortTypeMatchups(gCurrentMove, gBattlerTarget)) { - gBattleStruct->distortedTypeMatchups |= 1u << gBattlerTarget; + gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = TRUE; gBattlerAbility = gBattlerTarget; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_TeraShellDistortingTypeMatchups; @@ -1952,19 +1900,21 @@ static inline u32 GetHoldEffectCritChanceIncrease(u32 battler, u32 holdEffect) return critStageIncrease; } +#define CRITICAL_HIT_BLOCKED -1 +#define CRITICAL_HIT_ALWAYS -2 s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk) { s32 critChance = 0; if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT) { - critChance = -1; + critChance = CRITICAL_HIT_BLOCKED; } else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS || gMovesInfo[move].alwaysCriticalHit || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) { - critChance = -2; + critChance = CRITICAL_HIT_ALWAYS; } else { @@ -1980,21 +1930,23 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec critChance = ARRAY_COUNT(sCriticalHitOdds) - 1; } - if (critChance != -1 && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)) + if (critChance != CRITICAL_HIT_BLOCKED && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR)) { // Record ability only if move had 100% chance to get a crit if (recordAbility) { - if (critChance == -2) + if (critChance == CRITICAL_HIT_ALWAYS) RecordAbilityBattle(battlerDef, abilityDef); else if (GetCriticalHitOdds(critChance) == 1) RecordAbilityBattle(battlerDef, abilityDef); } - critChance = -1; + critChance = CRITICAL_HIT_BLOCKED; } return critChance; } +#undef CRIT_BLOCKED +#undef ALWAYS_CRITS s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility) { @@ -2264,6 +2216,7 @@ static void Cmd_adjustdamage(void) } if (gSpecialStatuses[gBattlerAttacker].gemBoost && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && gBattleMons[gBattlerAttacker].item && gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE && gCurrentMove != MOVE_STRUGGLE) @@ -2676,8 +2629,24 @@ static void Cmd_resultmessage(void) return; } + if (gMoveResultFlags & MOVE_RESULT_MISSED && !(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED))) + { + if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_BLUNDER_POLICY + && !IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)) + gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks + } + if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK)) { + if (gMultiHitCounter && gMultiHitCounter < gMovesInfo[gCurrentMove].strikeCount) + { + gMultiHitCounter = 0; + gMoveResultFlags &= ~MOVE_RESULT_MISSED; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings; + return; + } + if (gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (IsDoubleBattle()) != 0); stringId = gMissStringIds[gBattleCommunication[MISS_TYPE]]; @@ -4157,6 +4126,15 @@ static void Cmd_tryfaintmon(void) } else { + if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS + && !(gAbsentBattlerFlags & (1u << battler)) + && !IsBattlerAlive(battler)) + { + gBattleMons[battler].ability = ABILITY_NONE; + BattleScriptPush(gBattlescriptCurrInstr); + gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; + return; + } if (cmd->battler == BS_ATTACKER) { destinyBondBattler = gBattlerTarget; @@ -5714,6 +5692,37 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; + case MOVEEND_ABSORB: + if (gMovesInfo[gCurrentMove].effect == EFFECT_ABSORB) + { + if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && gMovesInfo[gCurrentMove].healingMove) + { + gBattleScripting.moveendState++; + break; + } + else if (IsBattlerAlive(gBattlerAttacker) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + gBattleMoveDamage = max(1, (gHpDealt * gMovesInfo[gCurrentMove].argument / 100)); + gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage); + gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE; + effect = TRUE; + if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIQUID_OOZE) + { + gBattleMoveDamage *= -1; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB_OOZE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_EffectAbsorbLiquidOoze; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_EffectAbsorb; + } + } + } + gBattleScripting.moveendState++; + break; case MOVEEND_RAGE: // rage check if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE && IsBattlerAlive(gBattlerTarget) @@ -6638,6 +6647,7 @@ static void Cmd_moveend(void) gSpecialStatuses[gBattlerAttacker].damagedMons = 0; gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0; gSpecialStatuses[gBattlerTarget].berryReduced = FALSE; + gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE; gBattleScripting.moveEffect = 0; gBattleStruct->hitSwitchTargetFailed = FALSE; gBattleStruct->isAtkCancelerForCalledMove = FALSE; @@ -6649,7 +6659,6 @@ static void Cmd_moveend(void) gBattleStruct->additionalEffectsCounter = 0; gBattleStruct->poisonPuppeteerConfusion = FALSE; gBattleStruct->fickleBeamBoosted = FALSE; - gBattleStruct->distortedTypeMatchups = 0; gBattleStruct->redCardActivates = FALSE; gBattleStruct->usedMicleBerry &= ~(1u << gBattlerAttacker); if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) @@ -7491,7 +7500,6 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) break; case ABILITY_FORECAST: case ABILITY_FLOWER_GIFT: - case ABILITY_ICE_FACE: case ABILITY_PROTOSYNTHESIS: if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0)) return TRUE; @@ -8774,6 +8782,7 @@ static void RemoveAllTerrains(void) break; } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain + TryToRevertMimicryAndFlags(); } #define DEFOG_CLEAR(status, structField, battlescript, move)\ @@ -11357,12 +11366,12 @@ static void Cmd_manipulatedamage(void) case DMG_FULL_ATTACKER_HP: gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker); break; - case DMG_CURR_ATTACKER_HP: - gBattleMoveDamage = GetNonDynamaxHP(gBattlerAttacker); - break; case DMG_BIG_ROOT: gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage); break; + case DMG_CURR_ATTACKER_HP: + gBattleMoveDamage = GetNonDynamaxHP(gBattlerAttacker); + break; case DMG_RECOIL_FROM_IMMUNE: gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2; break; @@ -11999,33 +12008,8 @@ static void Cmd_twoturnmoveschargestringandanimation(void) gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_setmultihitcounter(void) +static void Cmd_unused_0x8d(void) { - CMD_ARGS(u8 value); - - if (cmd->value) - { - gMultiHitCounter = cmd->value; - } - else - { - if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK) - { - gMultiHitCounter = 5; - } - else - { - // WARNING: These seem to be unused, see SetRandomMultiHitCounter. - if (B_MULTI_HIT_CHANCE >= GEN_5) - // 35%: 2 hits, 35%: 3 hits, 15% 4 hits, 15% 5 hits. - gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 7, 7, 3, 3); - else - // 37.5%: 2 hits, 37.5%: 3 hits, 12.5% 4 hits, 12.5% 5 hits. - gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 3, 3, 1, 1); - } - } - - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_initmultihitstring(void) @@ -14783,7 +14767,7 @@ static void Cmd_switchoutabilities(void) MarkBattlerForControllerExec(battler); break; case ABILITY_REGENERATOR: - gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 3; + gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 3; gBattleMoveDamage += gBattleMons[battler].hp; if (gBattleMoveDamage > gBattleMons[battler].maxHP) gBattleMoveDamage = gBattleMons[battler].maxHP; diff --git a/src/battle_util.c b/src/battle_util.c index bb0dc2c33c79..b8a4653d5650 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -147,8 +147,6 @@ void HandleAction_UseMove(void) gBattleScripting.savedMoveEffect = 0; gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker); - gBattleStruct->obedienceResult = GetAttackerObedienceForAction(); - // choose move if (gProtectStructs[gBattlerAttacker].noValidMoves) { @@ -1591,7 +1589,7 @@ u32 GetBattlerAffectionHearts(u32 battler) return GetMonAffectionHearts(&party[gBattlerPartyIndexes[battler]]); } -static void TryToRevertMimicryAndFlags(void) +void TryToRevertMimicryAndFlags(void) { u32 i; @@ -2436,12 +2434,25 @@ u8 DoBattlerEndTurnEffects(void) && !IsBattlerProtectedByMagicGuard(battler, ability)) { gBattlerTarget = gStatuses3[battler] & STATUS3_LEECHSEED_BATTLER; // Notice gBattlerTarget is actually the HP receiver. - gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; + gBattlerAttacker = battler; gBattleScripting.animArg1 = gBattlerTarget; gBattleScripting.animArg2 = gBattlerAttacker; - BattleScriptExecute(BattleScript_LeechSeedTurnDrain); + gBattleMoveDamage = max(1, GetNonDynamaxMaxHP(battler) / 8); + gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE; + if (GetBattlerAbility(battler) == ABILITY_LIQUID_OOZE) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_OOZE; + BattleScriptExecute(BattleScript_LeechSeedTurnDrainLiquidOoze); + } + else if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) + { + BattleScriptExecute(BattleScript_LeechSeedTurnDrainHealBlock); + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_DRAIN; + BattleScriptExecute(BattleScript_LeechSeedTurnDrainRecovery); + } effect++; } gBattleStruct->turnEffectsTracker++; @@ -2763,7 +2774,7 @@ u8 DoBattlerEndTurnEffects(void) && !IsLeafGuardProtected(battler)) { CancelMultiTurnMoves(battler); - gEffectBattler = battler; + gEffectBattler = gBattlerTarget = battler; if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN)) { gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_ELECTRIC; @@ -3206,7 +3217,8 @@ void SetAtkCancellerForCalledMove(void) u8 AtkCanceller_UnableToUseMove(u32 moveType) { - u8 effect = 0; + u32 effect = 0; + u32 obedienceResult; do { switch (gBattleStruct->atkCancellerTracker) @@ -3292,6 +3304,62 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_OBEDIENCE: + obedienceResult = GetAttackerObedienceForAction(); + if (obedienceResult != OBEYS + && !(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves + && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + switch (obedienceResult) + { + case DISOBEYS_LOAFS: + // Randomly select, then print a disobedient string + // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE + gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS); + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + gMoveResultFlags |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_HITS_SELF: + gBattlerTarget = gBattlerAttacker; + struct DamageCalculationData damageCalcData; + damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker; + damageCalcData.move = MOVE_NONE; + damageCalcData.moveType = TYPE_MYSTERY; + damageCalcData.isCrit = FALSE; + damageCalcData.randomFactor = FALSE; + damageCalcData.updateFlags = TRUE; + gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, 40); + gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gHitMarker |= HITMARKER_OBEYS; + break; + case DISOBEYS_FALL_ASLEEP: + if (FlagGet(B_FLAG_SLEEP_CLAUSE)) + gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; + gMoveResultFlags |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_WHILE_ASLEEP: + gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep; + gMoveResultFlags |= MOVE_RESULT_MISSED; + break; + case DISOBEYS_RANDOM_MOVE: + gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; + SetAtkCancellerForCalledMove(); + gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; + gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); + gHitMarker |= HITMARKER_DISOBEDIENT_MOVE; + gHitMarker |= HITMARKER_OBEYS; + break; + } + effect = 1; + } + else + { + gHitMarker |= HITMARKER_OBEYS; + } + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_TRUANT: // truant if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) { @@ -3547,7 +3615,6 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4; if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE - || gBattleStruct->obedienceResult != OBEYS || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE)) gBattlescriptCurrInstr = BattleScript_MoveUsedPowder; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; @@ -3568,8 +3635,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) gBattleStruct->atkCancellerTracker++; break; case CANCELLER_Z_MOVES: - if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE - && gBattleStruct->obedienceResult == OBEYS) + if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) { // For Z-Mirror Move, so it doesn't play the animation twice. bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE); @@ -6439,17 +6505,8 @@ bool32 TryPrimalReversion(u32 battler) if (GetBattlerHoldEffect(battler, FALSE) == HOLD_EFFECT_PRIMAL_ORB && GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE) { - if (gBattlerAttacker == battler) - { - BattleScriptPushCursorAndCallback(BattleScript_PrimalReversion); - } - else - { - // edge case for scenarios like a switch-in after activated eject button - gBattleScripting.savedBattler = gBattlerAttacker; - gBattlerAttacker = battler; - BattleScriptPushCursorAndCallback(BattleScript_PrimalReversionRestoreAttacker); - } + gBattleScripting.battler = battler; + BattleScriptPushCursorAndCallback(BattleScript_PrimalReversion); return TRUE; } return FALSE; @@ -6902,7 +6959,7 @@ static u8 TrySetEnigmaBerry(u32 battler) { if (IsBattlerAlive(battler) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) - && ((TARGET_TURN_DAMAGED && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements) + && ((BATTLER_TURN_DAMAGED(battler) && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements) && !(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP) && (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))) { @@ -6926,7 +6983,7 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category) || (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && GetBattleMoveCategory(gCurrentMove) == category && battler != gBattlerAttacker - && TARGET_TURN_DAMAGED)) + && BATTLER_TURN_DAMAGED(battler))) ) { BufferStatChange(battler, statId, STRINGID_STATROSE); @@ -8603,15 +8660,6 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk) bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) { - // Decorate bypasses protect and detect, but not crafty shield - if (move == MOVE_DECORATE) - { - if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD) - return TRUE; - else if (gProtectStructs[battlerDef].protected) - return FALSE; - } - // Z-Moves and Max Moves bypass protection (except Max Guard). if ((IsZMove(move) || IsMaxMove(move)) && (!gProtectStructs[battlerDef].maxGuarded @@ -10460,7 +10508,7 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move mod = UQ_4_12(1.0); } - if (gBattleStruct->distortedTypeMatchups & (1u << battlerDef) || (AI_DATA->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef))) + if (gSpecialStatuses[battlerDef].distortedTypeMatchups || (AI_DATA->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef))) { mod = UQ_4_12(0.5); if (recordAbilities) @@ -10744,6 +10792,7 @@ bool32 DoesSpeciesUseHoldItemToChangeForm(u16 species, u16 heldItemId) case FORM_CHANGE_BATTLE_PRIMAL_REVERSION: case FORM_CHANGE_BATTLE_ULTRA_BURST: case FORM_CHANGE_ITEM_HOLD: + case FORM_CHANGE_BEGIN_BATTLE: if (formChanges[i].param1 == heldItemId) return TRUE; break; @@ -10964,6 +11013,10 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method) if (GetBattlerTeraType(battler) == formChanges[i].param1) targetSpecies = formChanges[i].targetSpecies; break; + case FORM_CHANGE_BATTLE_ATTACK: + case FORM_CHANGE_BATTLE_KINGS_SHIELD: + targetSpecies = formChanges[i].targetSpecies; + break; } } } diff --git a/src/contest.c b/src/contest.c index 16e5fde9afcf..e03d5e8b3b84 100644 --- a/src/contest.c +++ b/src/contest.c @@ -949,23 +949,22 @@ static const struct CompressedSpriteSheet sSpriteSheets_ContestantsTurnBlinkEffe } }; -// Yup this is super dangerous but that's how it is here static const struct SpritePalette sSpritePalettes_ContestantsTurnBlinkEffect[CONTESTANT_COUNT] = { { - .data = (u16 *)(gHeap + 0x1A0A4), + .data = eContestTempSave.cachedWindowPalettes[5], .tag = TAG_BLINK_EFFECT_CONTESTANT0 }, { - .data = (u16 *)(gHeap + 0x1A0C4), + .data = eContestTempSave.cachedWindowPalettes[6], .tag = TAG_BLINK_EFFECT_CONTESTANT1 }, { - .data = (u16 *)(gHeap + 0x1A0E4), + .data = eContestTempSave.cachedWindowPalettes[7], .tag = TAG_BLINK_EFFECT_CONTESTANT2 }, { - .data = (u16 *)(gHeap + 0x1A104), + .data = eContestTempSave.cachedWindowPalettes[8], .tag = TAG_BLINK_EFFECT_CONTESTANT3 } }; diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index 956a2d0f2306..b5b3e539c87e 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -24,7 +24,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_ABSORB] = { - .battleScript = BattleScript_EffectAbsorb, + .battleScript = BattleScript_EffectHit, .battleTvScore = 4, }, diff --git a/src/data/moves_info.h b/src/data/moves_info.h index db5f2eaf7529..180d0d74ac60 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -1874,6 +1874,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 50, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_PREV_MON, @@ -1895,6 +1896,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 50, .zMove = { .powerOverride = 120 }, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -3620,6 +3622,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, + .argument = 50, .makesContact = TRUE, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -5152,6 +5155,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 50, .ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4), .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, @@ -8488,7 +8492,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .type = TYPE_NORMAL, .accuracy = 0, .pp = 40, - .target = MOVE_TARGET_USER, + .target = MOVE_TARGET_USER, // Targeting is handled through the script .priority = 0, .category = DAMAGE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_ATK_UP_1 }, @@ -10264,6 +10268,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, + .argument = 50, .makesContact = TRUE, .punchingMove = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, @@ -12212,7 +12217,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = { .name = COMPOUND_STRING("Coil"), .description = COMPOUND_STRING( - "Coils up to raise Attack\n" + "Coils up to raise Attack,\n" "Defense and Accuracy."), .effect = EFFECT_COIL, .power = 0, @@ -13244,6 +13249,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, + .argument = 50, .makesContact = TRUE, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, @@ -14200,6 +14206,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_FOES_AND_ALLY, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 50, .healingMove = B_HEAL_BLOCKING >= GEN_6, .contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION, .contestCategory = CONTEST_CATEGORY_BEAUTY, @@ -14414,7 +14421,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .type = TYPE_FAIRY, .accuracy = 0, .pp = 10, - .target = MOVE_TARGET_ALL_BATTLERS, + .target = MOVE_TARGET_USER, // The targeting of Flower Shield is handled through a script .priority = 0, .category = DAMAGE_CATEGORY_STATUS, .zMove = { .effect = Z_EFFECT_DEF_UP_1 }, @@ -17328,7 +17335,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = COMPOUND_STRING("Octolock"), .description = COMPOUND_STRING( "Traps the foe to lower Def\n" - "and Sp. Def fall each turn."), + "and Sp. Def each turn."), .effect = EFFECT_OCTOLOCK, .power = 0, .type = TYPE_FIGHTING, @@ -20021,6 +20028,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_SELECTED, .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, + .argument = 50, .makesContact = TRUE, .slicingMove = TRUE, .healingMove = TRUE, @@ -20322,6 +20330,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .target = MOVE_TARGET_BOTH, .priority = 0, .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 50, .thawsUser = TRUE, .metronomeBanned = TRUE, .healingMove = B_EXTRAPOLATED_MOVE_FLAGS, @@ -20601,6 +20610,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, + .minimizeDoubleDamage = TRUE, .battleAnimScript = gBattleAnimMove_SupercellSlam, }, diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index 46dec5354435..4af68ce31825 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -789,9 +789,11 @@ static const struct FormChange sFurfrouFormChangeTable[] = { #if P_FAMILY_HONEDGE static const struct FormChange sAegislashFormChangeTable[] = { - {FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD}, - {FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD}, - {FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD}, + {FORM_CHANGE_BATTLE_ATTACK, SPECIES_AEGISLASH_BLADE}, + {FORM_CHANGE_BATTLE_KINGS_SHIELD, SPECIES_AEGISLASH_SHIELD}, + {FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD}, + {FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD}, + {FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD}, {FORM_CHANGE_TERMINATOR}, }; #endif //P_FAMILY_HONEDGE diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index fa8c8d9fde94..ba9f845395b9 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -4762,7 +4762,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .palette = gMonPalette_VulpixAlola, .shinyPalette = gMonShinyPalette_VulpixAlola, .iconSprite = gMonIcon_VulpixAlola, - .iconPalIndex = 2, + .iconPalIndex = 0, SHADOW(-2, 3, SHADOW_SIZE_M) FOOTPRINT(Vulpix) OVERWORLD( @@ -4829,7 +4829,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .palette = gMonPalette_NinetalesAlola, .shinyPalette = gMonShinyPalette_NinetalesAlola, .iconSprite = gMonIcon_NinetalesAlola, - .iconPalIndex = 2, + .iconPalIndex = 0, SHADOW(0, 12, SHADOW_SIZE_XL_BATTLE_ONLY) FOOTPRINT(Ninetales) OVERWORLD( @@ -8709,7 +8709,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .palette = gMonPalette_GravelerAlola, .shinyPalette = gMonShinyPalette_GravelerAlola, .iconSprite = gMonIcon_GravelerAlola, - .iconPalIndex = 2, + .iconPalIndex = 0, SHADOW(1, 5, SHADOW_SIZE_XL_BATTLE_ONLY) FOOTPRINT(Graveler) OVERWORLD( diff --git a/src/data/pokemon/species_info/gen_7_families.h b/src/data/pokemon/species_info/gen_7_families.h index d42167b88319..cb126fd171a4 100644 --- a/src/data/pokemon/species_info/gen_7_families.h +++ b/src/data/pokemon/species_info/gen_7_families.h @@ -5493,7 +5493,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .palette = gMonPalette_TapuFini, .shinyPalette = gMonShinyPalette_TapuFini, .iconSprite = gMonIcon_TapuFini, - .iconPalIndex = 0, + .iconPalIndex = 2, SHADOW(1, 15, SHADOW_SIZE_M) FOOTPRINT(TapuFini) OVERWORLD( @@ -5694,7 +5694,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .palette = gMonPalette_Solgaleo, .shinyPalette = gMonShinyPalette_Solgaleo, .iconSprite = gMonIcon_Solgaleo, - .iconPalIndex = 0, + .iconPalIndex = 2, SHADOW(-1, 11, SHADOW_SIZE_XL_BATTLE_ONLY) FOOTPRINT(Solgaleo) OVERWORLD( @@ -5826,7 +5826,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .palette = gMonPalette_Nihilego, .shinyPalette = gMonShinyPalette_Nihilego, .iconSprite = gMonIcon_Nihilego, - .iconPalIndex = 0, + .iconPalIndex = 2, SHADOW(-2, 14, SHADOW_SIZE_S) FOOTPRINT(Nihilego) OVERWORLD( @@ -6220,7 +6220,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .palette = gMonPalette_Guzzlord, .shinyPalette = gMonShinyPalette_Guzzlord, .iconSprite = gMonIcon_Guzzlord, - .iconPalIndex = 0, + .iconPalIndex = 2, SHADOW(4, 10, SHADOW_SIZE_XL_BATTLE_ONLY) FOOTPRINT(Guzzlord) OVERWORLD( @@ -6288,7 +6288,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .palette = gMonPalette_Necrozma, .shinyPalette = gMonShinyPalette_Necrozma, .iconSprite = gMonIcon_Necrozma, - .iconPalIndex = 0, + .iconPalIndex = 1, SHADOW(-1, 15, SHADOW_SIZE_M) FOOTPRINT(Necrozma) OVERWORLD( diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index 7b5fcdd3d1eb..d617d36f1b0a 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -2619,7 +2619,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .trainerOffset = 0, .frontPic = gMonFrontPic_Maschiff, .frontPicSize = MON_COORDS_SIZE(64, 64), - .frontPicYOffset = 8, + .frontPicYOffset = 11, .frontAnimFrames = sAnims_Maschiff, //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, .backPic = gMonBackPic_Maschiff, @@ -7341,12 +7341,12 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .trainerOffset = 0, .frontPic = gMonFrontPic_Fezandipiti, .frontPicSize = MON_COORDS_SIZE(64, 64), - .frontPicYOffset = 2, + .frontPicYOffset = 1, .frontAnimFrames = sAnims_Fezandipiti, //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, .backPic = gMonBackPic_Fezandipiti, .backPicSize = MON_COORDS_SIZE(64, 64), - .backPicYOffset = 4, + .backPicYOffset = 0, //.backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_Fezandipiti, .shinyPalette = gMonShinyPalette_Fezandipiti, diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h index 8452e24732c7..deceeb04204c 100644 --- a/src/data/pokemon_graphics/front_pic_anims.h +++ b/src/data/pokemon_graphics/front_pic_anims.h @@ -5205,8 +5205,7 @@ static const union AnimCmd sAnim_DeoxysNormal_1[] = { ANIMCMD_FRAME(0, 16), ANIMCMD_FRAME(1, 16), - ANIMCMD_FRAME(0, 26), - ANIMCMD_FRAME(1, 16), + ANIMCMD_FRAME(1, 26), ANIMCMD_FRAME(0, 16), ANIMCMD_END, }; diff --git a/src/line_break.c b/src/line_break.c new file mode 100644 index 000000000000..b8888f501f8d --- /dev/null +++ b/src/line_break.c @@ -0,0 +1,281 @@ +#include "global.h" +#include "line_break.h" +#include "text.h" +#include "malloc.h" + +void StripLineBreaks(u8 *src) +{ + u32 currIndex = 0; + while (src[currIndex] != EOS) + { + if (src[currIndex] == CHAR_PROMPT_SCROLL || src[currIndex] == CHAR_NEWLINE) + src[currIndex] = CHAR_SPACE; + currIndex++; + } +} + +void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) +{ + u32 currIndex = 0; + u8 *currSrc = src; + while (src[currIndex] != EOS) + { + if (src[currIndex] == CHAR_PROMPT_CLEAR) + { + u8 replacedChar = src[currIndex + 1]; + src[currIndex + 1] = EOS; + BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId); + src[currIndex + 1] = replacedChar; + currSrc = &src[currIndex + 1]; + } + currIndex++; + } + BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId); +} + +void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) +{ + // If the string already has line breaks, don't interfere with them + if (StringHasManualBreaks(src)) + return; + // Sanity check + if (src[0] == EOS) + return; + u32 numChars = 1; + u32 numWords = 1; + u32 currWordIndex = 0; + u32 currWordLength = 1; + bool32 isPrevCharSplitting = FALSE; + bool32 isCurrCharSplitting; + // Get numbers of chars in string and count words + while (src[numChars] != EOS) + { + isCurrCharSplitting = IsWordSplittingChar(src, numChars); + if (isCurrCharSplitting && !isPrevCharSplitting) + numWords++; + isPrevCharSplitting = isCurrCharSplitting; + numChars++; + } + // Allocate enough space for word data + struct StringWord *allWords = Alloc(numWords*sizeof(struct StringWord)); + + allWords[currWordIndex].startIndex = 0; + allWords[currWordIndex].width = 0; + isPrevCharSplitting = FALSE; + // Fill in word begin index and lengths + for (u32 i = 1; i < numChars; i++) + { + isCurrCharSplitting = IsWordSplittingChar(src, i); + if (isCurrCharSplitting && !isPrevCharSplitting) + { + allWords[currWordIndex].length = currWordLength; + currWordIndex++; + currWordLength = 0; + } + else if (!isCurrCharSplitting && isPrevCharSplitting) + { + allWords[currWordIndex].startIndex = i; + allWords[currWordIndex].width = 0; + currWordLength++; + } + else + { + currWordLength++; + } + isPrevCharSplitting = isCurrCharSplitting; + } + allWords[currWordIndex].length = currWordLength; + + // Fill in individual word widths + for (u32 i = 0; i < numWords; i++) + { + for (u32 j = 0; j < allWords[i].length; j++) + allWords[i].width += GetGlyphWidth(src[allWords[i].startIndex + j], FALSE, fontId); + } + + // Step 1: Does it all fit one one line? Then no break + // Step 2: Try to split across minimum number of lines + u32 spaceWidth = GetGlyphWidth(0, FALSE, fontId); + u32 totalWidth = allWords[0].width; + // Calculate total widths without any line breaks + for (u32 i = 1; i < numWords; i++) + totalWidth += allWords[i].width + spaceWidth; + + // If it doesn't fit on 1 line, do fancy line break calculation + // NOTE: Currently the line break calculation isn't fancy + if (totalWidth > maxWidth) + { + // Figure out how many lines are needed with naive method + u32 currLineWidth = 0; + u32 totalLines = 1; + bool32 shouldTryAgain; + for (currWordIndex = 0; currWordIndex < numWords; currWordIndex++) + { + if (currLineWidth + allWords[currWordIndex].length > maxWidth) + { + totalLines++; + currLineWidth = allWords[currWordIndex].width; + } + else + { + currLineWidth += allWords[currWordIndex].width + spaceWidth; + } + } + // LINE LAYOUT STARTS HERE + struct StringLine *stringLines; + do + { + shouldTryAgain = FALSE; + u16 targetLineWidth = totalWidth/totalLines; + stringLines = Alloc(totalLines*sizeof(struct StringLine)); + for (u32 lineIndex = 0; lineIndex < totalLines; lineIndex++) + { + stringLines[lineIndex].numWords = 0; + stringLines[lineIndex].spaceWidth = spaceWidth; + stringLines[lineIndex].extraSpaceWidth = 0; + } + currWordIndex = 0; + u16 currLineIndex = 0; + stringLines[currLineIndex].words = &allWords[currWordIndex]; + stringLines[currLineIndex].numWords = 1; + currLineWidth = allWords[currWordIndex].width; + currWordIndex++; + while (currWordIndex < numWords) + { + if (currLineWidth + spaceWidth + allWords[currWordIndex].width > maxWidth) + { + // go to next line + currLineIndex++; + if (currLineIndex == totalLines) + { + totalLines++; + Free(stringLines); + shouldTryAgain = TRUE; + break; + } + stringLines[currLineIndex].words = &allWords[currWordIndex]; + stringLines[currLineIndex].numWords = 1; + currLineWidth = allWords[currWordIndex].width; + currWordIndex++; + } + else if (currLineWidth > targetLineWidth) + { + // go to next line + currLineIndex++; + if (currLineIndex == totalLines) + { + totalLines++; + Free(stringLines); + shouldTryAgain = TRUE; + break; + } + stringLines[currLineIndex].words = &allWords[currWordIndex]; + stringLines[currLineIndex].numWords = 1; + currLineWidth = allWords[currWordIndex].width; + currWordIndex++; + } + else + { + // continue on current line + // add word and space width + currLineWidth += spaceWidth + allWords[currWordIndex].width; + stringLines[currLineIndex].numWords++; + currWordIndex++; + } + } + } while (shouldTryAgain); + //u32 currBadness = GetStringBadness(stringLines, totalLines, maxWidth); + BuildNewString(stringLines, totalLines, screenLines, src); + Free(stringLines); + } + + Free(allWords); +} + +// Only allow word splitting on allowed chars +bool32 IsWordSplittingChar(const u8 *src, u32 index) +{ + switch (src[index]) + { + case CHAR_SPACE: + return TRUE; + default: + return FALSE; + } +} + +// Badness calculation +// unfilled lines scale linerarly +// jagged lines scales by the square +// runts scale linearly +// numbers not final +// ISN'T ACTUALLY USED RIGHT NOW +u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth) +{ + u32 badness = 0; + u32 *lineWidths = Alloc(numLines*4); + u32 widestWidth = 0; + for (u32 i = 0; i < numLines; i++) + { + lineWidths[i] = 0; + for (u32 j = 0; j < stringLines[i].numWords; j++) + lineWidths[i] += stringLines[i].words[j].width; + lineWidths[i] += (stringLines[i].numWords-1)*stringLines[i].spaceWidth; + if (lineWidths[i] > widestWidth) + widestWidth = lineWidths[i]; + if (stringLines[i].numWords == 1) + badness += BADNESS_RUNT; + } + for (u32 i = 0; i < numLines; i++) + { + u32 extraSpaceWidth = 0; + if (lineWidths[i] != widestWidth) + { + // Not the best way to do this, ideally a line should be allowed to get longer than current widest + // line. But then the widest line has to be recalculated. + while (lineWidths[i] + (extraSpaceWidth + 1) * (stringLines[i].numWords - 1) < widestWidth && extraSpaceWidth < MAX_SPACE_WIDTH) + extraSpaceWidth++; + lineWidths[i] += extraSpaceWidth*(stringLines[i].numWords-1); + } + badness += (maxWidth - lineWidths[i]) * BADNESS_UNFILLED; + u32 baseBadness = (widestWidth - lineWidths[i]) * BADNESS_JAGGED; + badness += baseBadness*baseBadness; + stringLines[i].extraSpaceWidth = extraSpaceWidth; + } + Free(lineWidths); + return badness; +} + +// Build the new string from the data stored in the StringLine structs +void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str) +{ + u32 srcCharIndex = 0; + for (u32 lineIndex = 0; lineIndex < numLines; lineIndex++) + { + srcCharIndex += stringLines[lineIndex].words[0].length; + for (u32 wordIndex = 1; wordIndex < stringLines[lineIndex].numWords; wordIndex++) + // Add length of word and a space + srcCharIndex += stringLines[lineIndex].words[wordIndex].length + 1; + if (lineIndex + 1 < numLines) + { + // Add the appropriate line break depending on line number + if (lineIndex >= maxLines - 1 && numLines > maxLines) + str[srcCharIndex] = CHAR_PROMPT_SCROLL; + else + str[srcCharIndex] = CHAR_NEWLINE; + srcCharIndex++; + } + } +} + +bool32 StringHasManualBreaks(u8 *src) +{ + u32 charIndex = 0; + while (src[charIndex] != EOS) + { + if (src[charIndex] == CHAR_PROMPT_SCROLL || src[charIndex] == CHAR_NEWLINE) + return TRUE; + charIndex++; + } + return FALSE; +} diff --git a/src/mini_printf.c b/src/mini_printf.c index c5b1e09bdc56..9332a270a4ed 100644 --- a/src/mini_printf.c +++ b/src/mini_printf.c @@ -86,6 +86,8 @@ static inline char mini_pchar_decode(char encoded) ret = '('; // opening parentheses else if (encoded == CHAR_RIGHT_PAREN) ret = ')'; // closing parentheses + else if (encoded == CHAR_HYPHEN) + ret = '-'; // hyphen return ret; } @@ -133,7 +135,31 @@ static s32 _putsEncoded(char *s, s32 len, void *buf) { break; } - *(b->pbuffer ++) = mini_pchar_decode(s[i]); + if (s[i] == CHAR_NEWLINE) + { + *(b->pbuffer ++) = '\\'; + *(b->pbuffer ++) = 'n'; + } + else if (s[i] == CHAR_PROMPT_SCROLL) + { + *(b->pbuffer ++) = '\\'; + *(b->pbuffer ++) = 'l'; + } + else if (s[i] == CHAR_PROMPT_CLEAR) + { + *(b->pbuffer ++) = '\\'; + *(b->pbuffer ++) = 'p'; + } + else if (s[i] == CHAR_ELLIPSIS) + { + *(b->pbuffer ++) = '.'; + *(b->pbuffer ++) = '.'; + *(b->pbuffer ++) = '.'; + } + else + { + *(b->pbuffer ++) = mini_pchar_decode(s[i]); + } } *(b->pbuffer) = 0; return b->pbuffer - p0; diff --git a/src/pokemon.c b/src/pokemon.c index 8197c803f2dc..743f5b2771ed 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4994,16 +4994,25 @@ u16 HoennToNationalOrder(u16 hoennNum) The function then loops over the 16x16 spot image. For each bit in the spot's binary image, if the bit is set then it's part of the spot; try to draw it. A pixel is drawn on Spinda if the - pixel on Spinda satisfies the following formula: ((u8)(colorIndex - 1) <= 2). The -1 excludes - transparent pixels, as these are index 0. Therefore only colors 1, 2, or 3 on Spinda will - allow a spot to be drawn. These color indexes are Spinda's light brown body colors. To create + pixel is between FIRST_SPOT_COLOR and LAST_SPOT_COLOR (so only colors 1, 2, or 3 on Spinda will + allow a spot to be drawn). These color indexes are Spinda's light brown body colors. To create the spot it adds 4 to the color index, so Spinda's spots will be colors 5, 6, and 7. - The above is done two different ways in the function: one with << 4, and one without. This - is because Spinda's sprite is a 4 bits per pixel image, but the pointer to Spinda's pixels + The above is done in TRY_DRAW_SPOT_PIXEL two different ways: one with << 4, and one without. + This is because Spinda's sprite is a 4 bits per pixel image, but the pointer to Spinda's pixels (destPixels) is an 8 bit pointer, so it addresses two pixels. Shifting by 4 accesses the 2nd of these pixels, so this is done every other time. */ + +// Draw spot pixel if this is Spinda's body color +#define TRY_DRAW_SPOT_PIXEL(pixels, shift) \ + if (((*(pixels) & (0xF << (shift))) >= (FIRST_SPOT_COLOR << (shift))) \ + && ((*(pixels) & (0xF << (shift))) <= (LAST_SPOT_COLOR << (shift)))) \ + { \ + *(pixels) += (SPOT_COLOR_ADJUSTMENT << (shift)); \ + } + + void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame) { s32 i; @@ -5045,16 +5054,12 @@ void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame) if (column & 1) { /* Draw spot pixel if this is Spinda's body color */ - if ((u8)((*destPixels & 0xF0) - (FIRST_SPOT_COLOR << 4)) - <= ((LAST_SPOT_COLOR - FIRST_SPOT_COLOR) << 4)) - *destPixels += (SPOT_COLOR_ADJUSTMENT << 4); + TRY_DRAW_SPOT_PIXEL(destPixels, 4); } else { /* Draw spot pixel if this is Spinda's body color */ - if ((u8)((*destPixels & 0xF) - FIRST_SPOT_COLOR) - <= (LAST_SPOT_COLOR - FIRST_SPOT_COLOR)) - *destPixels += SPOT_COLOR_ADJUSTMENT; + TRY_DRAW_SPOT_PIXEL(destPixels, 0); } } diff --git a/test/battle/ability/dauntless_shield.c b/test/battle/ability/dauntless_shield.c index ca9125e14f26..ada4ace7866a 100644 --- a/test/battle/ability/dauntless_shield.c +++ b/test/battle/ability/dauntless_shield.c @@ -3,7 +3,7 @@ ASSUMPTIONS { - ASSUME(B_PROTEAN_LIBERO == GEN_9); + ASSUME(B_DAUNTLESS_SHIELD == GEN_9); } SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage") diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c index 54a307754c96..22b67a7a5369 100644 --- a/test/battle/ability/ice_face.c +++ b/test/battle/ability/ice_face.c @@ -135,3 +135,33 @@ SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is MESSAGE("Eiscue fainted!"); } } + +SINGLE_BATTLE_TEST("Ice Face is not restored if hail or snow and Eiscue are already out") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, move); } + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + NONE_OF { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } + } +} diff --git a/test/battle/ability/intimidate.c b/test/battle/ability/intimidate.c index 1278a45866fd..e0f97d5bdaf2 100644 --- a/test/battle/ability/intimidate.c +++ b/test/battle/ability/intimidate.c @@ -246,7 +246,7 @@ DOUBLE_BATTLE_TEST("Intimidate is not going to trigger if a mon switches out thr } } -SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas") +SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas - switching out") { GIVEN { PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } @@ -263,3 +263,91 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutral SEND_IN_MESSAGE("Wobbuffet"); } } + +SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - switching moves") +{ + u32 move; + PARAMETRIZE { move = MOVE_U_TURN; } + PARAMETRIZE { move = MOVE_HEALING_WISH; } + PARAMETRIZE { move = MOVE_BATON_PASS; } + GIVEN { + ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); + ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH); + ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { MOVE(player, move); SEND_OUT(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + ANIMATION(ANIM_TYPE_MOVE, move, player); + MESSAGE("The effects of the neutralizing gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + SEND_IN_MESSAGE("Wobbuffet"); + } THEN { + if (move == MOVE_HEALING_WISH) + EXPECT_EQ(player->hp, player->maxHP); + } +} + +SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - opponent caused switches") +{ + u32 move, item; + PARAMETRIZE { move = MOVE_TACKLE; item = ITEM_EJECT_BUTTON; } + PARAMETRIZE { move = MOVE_GROWL; item = ITEM_EJECT_PACK; } + PARAMETRIZE { move = MOVE_ROAR; item = ITEM_NONE; } + PARAMETRIZE { move = MOVE_DRAGON_TAIL; item = ITEM_NONE; } + GIVEN { + ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON); + ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK); + ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN); + ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR); + ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET); + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Item(item); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + if (item != ITEM_NONE) { + TURN { MOVE(opponent, move); SEND_OUT(player, 1); } + } else { + TURN { MOVE(opponent, move); } + } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + if (item != ITEM_NONE) + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("The effects of the neutralizing gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + if (item != ITEM_NONE) { + SEND_IN_MESSAGE("Wobbuffet"); + } else { + MESSAGE("Wobbuffet was dragged out!"); + } + } +} + +SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - fainted") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_FELL_STINGER].effect == EFFECT_FELL_STINGER); + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_FELL_STINGER); SEND_OUT(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FELL_STINGER, opponent); + MESSAGE("The effects of the neutralizing gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + MESSAGE("Weezing fainted!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + SEND_IN_MESSAGE("Wobbuffet"); + } +} + diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c index 71c960fcc5dc..0883e3cc5996 100644 --- a/test/battle/ai/ai.c +++ b/test/battle/ai/ai.c @@ -806,3 +806,28 @@ AI_SINGLE_BATTLE_TEST("AI uses a guaranteed KO move instead of the move with the NOT MESSAGE("Wobbuffet fainted!"); } } + +AI_SINGLE_BATTLE_TEST("AI stays choice locked into moves in spite of the player's ability disabling them") +{ + u32 playerMon, ability, aiMove; + PARAMETRIZE { ability = ABILITY_DAZZLING; playerMon = SPECIES_BRUXISH; aiMove = MOVE_QUICK_ATTACK; } + PARAMETRIZE { ability = ABILITY_QUEENLY_MAJESTY; playerMon = SPECIES_TSAREENA; aiMove = MOVE_QUICK_ATTACK; } + PARAMETRIZE { ability = ABILITY_ARMOR_TAIL; playerMon = SPECIES_FARIGIRAF; aiMove = MOVE_QUICK_ATTACK; } + PARAMETRIZE { ability = ABILITY_SOUNDPROOF; playerMon = SPECIES_EXPLOUD; aiMove = MOVE_BOOMBURST; } + PARAMETRIZE { ability = ABILITY_BULLETPROOF; playerMon = SPECIES_CHESNAUGHT; aiMove = MOVE_BULLET_SEED; } + + GIVEN { + ASSUME(gItemsInfo[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND); + ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1); + ASSUME(gMovesInfo[MOVE_BOOMBURST].soundMove == TRUE); + ASSUME(gMovesInfo[MOVE_BULLET_SEED].ballisticMove == TRUE); + ASSUME(gMovesInfo[MOVE_TAIL_WHIP].category == DAMAGE_CATEGORY_STATUS); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(playerMon) { Ability(ability); } + OPPONENT(SPECIES_SMEARGLE) { Item(ITEM_CHOICE_BAND); Moves(aiMove, MOVE_TACKLE); } + } WHEN { + TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, aiMove); } + TURN { EXPECT_MOVE(opponent, aiMove); } + } +} diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 5610689f49e1..7f2368261d17 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -895,3 +895,17 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch into mon with good type matchup TURN { MOVE(player, MOVE_TACKLE); EXPECT_SWITCH(opponent, 1); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI correctly handles abilities when scoring moves") +{ + GIVEN { + ASSUME(B_PRANKSTER_DARK_TYPES >= GEN_7); + ASSUME(gSpeciesInfo[SPECIES_GRENINJA].types[1] == TYPE_DARK); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES); + PLAYER(SPECIES_GRENINJA) { Moves(MOVE_WATER_GUN); } + OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_PRANKSTER); Moves(MOVE_LEECH_SEED, MOVE_STUN_SPORE, MOVE_ABSORB); } + OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_INFILTRATOR); } + } WHEN { + TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_ABSORB); } + } +} diff --git a/test/battle/hold_effect/blunder_policy.c b/test/battle/hold_effect/blunder_policy.c new file mode 100644 index 000000000000..552ad2f6fbd5 --- /dev/null +++ b/test/battle/hold_effect/blunder_policy.c @@ -0,0 +1,67 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_BLUNDER_POLICY].holdEffect == HOLD_EFFECT_BLUNDER_POLICY); +} + +SINGLE_BATTLE_TEST("Blunder Policy raises the users speed by 2 stages if the user misses") +{ + PASSES_RANDOMLY(3, 10, RNG_ACCURACY); + GIVEN { + ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FOCUS_BLAST); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + } THEN { + EXPECT(player->item == ITEM_NONE); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2); + } +} + + +SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to an immunity") +{ + PASSES_RANDOMLY(10, 10, RNG_ACCURACY); + GIVEN { + ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } + OPPONENT(SPECIES_GASTLY); + } WHEN { + TURN { MOVE(player, MOVE_FOCUS_BLAST); } + } SCENE { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + } + } THEN { + EXPECT(player->item == ITEM_BLUNDER_POLICY); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE); + } +} + +SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to Protect") +{ + PASSES_RANDOMLY(10, 10, RNG_ACCURACY); + GIVEN { + ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_FOCUS_BLAST); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + } + } THEN { + EXPECT(player->item == ITEM_BLUNDER_POLICY); + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE); + } +} diff --git a/test/battle/hold_effect/enigma_berry.c b/test/battle/hold_effect/enigma_berry.c index 5a058eed1b48..762774f25d25 100644 --- a/test/battle/hold_effect/enigma_berry.c +++ b/test/battle/hold_effect/enigma_berry.c @@ -58,3 +58,19 @@ SINGLE_BATTLE_TEST("Enigma Berry does nothing if Heal Block applies") } } } + +DOUBLE_BATTLE_TEST("Enigma Berry doesn't trigger if partner was hit") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT) { Item(ITEM_ENIGMA_BERRY); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); + } THEN { + EXPECT(opponentRight->item == ITEM_ENIGMA_BERRY); + } +} diff --git a/test/battle/hold_effect/kee_berry.c b/test/battle/hold_effect/kee_berry.c index 2375e65c2fb6..26cd2152a188 100644 --- a/test/battle/hold_effect/kee_berry.c +++ b/test/battle/hold_effect/kee_berry.c @@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Kee Berry doesn't trigger if the item hold user used a physi EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE); } } + +DOUBLE_BATTLE_TEST("Kee Berry doesn't trigger if partner was hit") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT) { Item(ITEM_KEE_BERRY); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); + } THEN { + EXPECT(opponentRight->item == ITEM_KEE_BERRY); + } +} diff --git a/test/battle/hold_effect/maranga_berry.c b/test/battle/hold_effect/maranga_berry.c index 6d12f257a76f..77cdaddf42f5 100644 --- a/test/battle/hold_effect/maranga_berry.c +++ b/test/battle/hold_effect/maranga_berry.c @@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Maranga Berry doesn't trigger if the item hold user used a s EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE); } } + +DOUBLE_BATTLE_TEST("Maranga Berry doesn't trigger if partner was hit") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT) { Item(ITEM_MARANGA_BERRY); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); + } THEN { + EXPECT(opponentRight->item == ITEM_MARANGA_BERRY); + } +} diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c index 8c36400c290f..aa312797b284 100644 --- a/test/battle/hold_effect/red_card.c +++ b/test/battle/hold_effect/red_card.c @@ -468,3 +468,25 @@ SINGLE_BATTLE_TEST("Red Card prevents Emergency Exit activation when triggered") } TO_DO_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed"); + +SINGLE_BATTLE_TEST("Red Card activates before Eject Pack") +{ + GIVEN { + ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_OVERHEAT); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet is switched out with the Eject Button!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + } +} diff --git a/test/battle/move_effect/absorb.c b/test/battle/move_effect/absorb.c index 698ea41091cf..d046876b1b25 100644 --- a/test/battle/move_effect/absorb.c +++ b/test/battle/move_effect/absorb.c @@ -24,6 +24,25 @@ SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt") } } +SINGLE_BATTLE_TEST("Absorb deals 50% of the damage dealt to user agains Liquid Ooze") +{ + s16 damage; + s16 healed; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + } WHEN { + TURN { MOVE(player, MOVE_ABSORB); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + } THEN { + EXPECT_MUL_EQ(damage, Q_4_12(0.5), healed); + } +} + SINGLE_BATTLE_TEST("Absorb fails if Heal Block applies") { GIVEN { @@ -69,5 +88,41 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar } } +DOUBLE_BATTLE_TEST("Matcha Gatcha will faint the pokemon if Liquid Ooze drain deals enough damage") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_MATCHA_GOTCHA].effect == EFFECT_ABSORB); + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft); + HP_BAR(opponentLeft); + HP_BAR(playerLeft); + MESSAGE("Wobbuffet sucked up the liquid ooze!"); + MESSAGE("Wobbuffet fainted!"); + } +} + +SINGLE_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt") +{ + s16 damage; + s16 healed; + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_DRAINING_KISS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAINING_KISS, player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + } THEN { + EXPECT_MUL_EQ(damage, Q_4_12(-0.75), healed); + } +} + TO_DO_BATTLE_TEST("Absorb recovers 50% of the damage dealt to a Substitute"); -TO_DO_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt"); // Tests .argument 's implementation diff --git a/test/battle/move_effect/curse.c b/test/battle/move_effect/curse.c index 5fe17d356101..0696dfc4cac2 100644 --- a/test/battle/move_effect/curse.c +++ b/test/battle/move_effect/curse.c @@ -34,3 +34,36 @@ SINGLE_BATTLE_TEST("Curse cuts the user's HP in half when used by Ghost-types") HP_BAR(player, hp: maxHP / 2); } } + +SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean") +{ + GIVEN { + PLAYER(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CURSE, target: player); } + } SCENE { + s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + ABILITY_POPUP(player, ABILITY_PROTEAN); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player); + HP_BAR(player, damage: playerMaxHP / 2); + HP_BAR(player, damage: playerMaxHP / 4); + } +} + +SINGLE_BATTLE_TEST("Curse applies to the opponent if user is afflicted by Trick-or-Treat in the same turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TRICK_OR_TREAT); MOVE(player, MOVE_CURSE, target: player); } + } SCENE { + s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + s32 opponentMaxHP = GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK_OR_TREAT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player); + HP_BAR(player, damage: playerMaxHP / 2); + HP_BAR(opponent, damage: opponentMaxHP / 4); + } +} diff --git a/test/battle/move_effect/flower_shield.c b/test/battle/move_effect/flower_shield.c new file mode 100644 index 000000000000..e31fc9e5cd1a --- /dev/null +++ b/test/battle/move_effect/flower_shield.c @@ -0,0 +1,37 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_FLOWER_SHIELD].effect == EFFECT_FLOWER_SHIELD); +} + +DOUBLE_BATTLE_TEST("Flower Shield raises the defense of all grass type pokemon") +{ + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_TANGROWTH].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_SUNKERN].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_SUNFLORA].types[0] == TYPE_GRASS); + PLAYER(SPECIES_TANGELA); + PLAYER(SPECIES_TANGROWTH); + OPPONENT(SPECIES_SUNKERN); + OPPONENT(SPECIES_SUNFLORA); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FLOWER_SHIELD); MOVE(playerRight, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Tangela used Flower Shield!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Tangela's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("The opposing Sunkern's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Tangrowth's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("The opposing Sunflora's Defense rose!"); + } +} diff --git a/test/battle/move_effect/hit_set_remove_terrain.c b/test/battle/move_effect/hit_set_remove_terrain.c index 98c6e179eb27..a48d316d3f6a 100644 --- a/test/battle/move_effect/hit_set_remove_terrain.c +++ b/test/battle/move_effect/hit_set_remove_terrain.c @@ -124,3 +124,35 @@ AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there i } } } + +SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner reverts typing on Mimicry users") +{ + u32 j; + static const u16 terrainMoves[] = + { + MOVE_ELECTRIC_TERRAIN, + MOVE_PSYCHIC_TERRAIN, + MOVE_GRASSY_TERRAIN, + MOVE_MISTY_TERRAIN, + }; + + u16 terrainMove = MOVE_NONE; + u16 removeTerrainMove = MOVE_NONE; + + for (j = 0; j < ARRAY_COUNT(terrainMoves); j++) + { + PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainMoves[j]; } + PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainMoves[j]; } + } + + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } + } WHEN { + TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } + TURN { MOVE(player, MOVE_TOXIC); } + } SCENE { + MESSAGE("It doesn't affect the opposing Stunfisk…"); + } +} diff --git a/test/battle/move_effect/knock_off.c b/test/battle/move_effect/knock_off.c index aa1081ff6726..61bb062a2540 100644 --- a/test/battle/move_effect/knock_off.c +++ b/test/battle/move_effect/knock_off.c @@ -202,6 +202,126 @@ SINGLE_BATTLE_TEST("Knock Off doesn't knock off items from Pokemon behind substi } WHEN { TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_KNOCK_OFF); } } SCENE { - NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Poké Ball"); + NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Poké Ball!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off does knock off Mega Stones from Pokemon that don't actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ABSOLITE); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Absolite!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off Mega Stones from Pokemon that actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ABSOL) { Item(ITEM_ABSOLITE); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Absol's Absolite!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off does knock off Orbs for Primal Reversion from Pokemon that don't actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_ORB); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Red Orb!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off Orbs for Primal Reversion from Pokemon that actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Groudon's Red Orb!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off Z-Crystals") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIUM_Z); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Electrium Z!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off Ultranecrozium Z from Pokemon that actually use it") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Necrozma's Ultranecrozium Z!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off does knock off other form-change hold items from Pokemon that don't actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SKY_PLATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Sky Plate!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off other form-change hold items from Pokemon that actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ARCEUS) { Item(ITEM_SKY_PLATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Arceus's Sky Plate!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off does knock off begin-battle form-change hold items from Pokemon that don't actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RUSTED_SHIELD); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Rusted Shield!"); + } +} + +SINGLE_BATTLE_TEST("Knock Off doesn't knock off begin-battle form-change hold items from Pokemon that actually use them") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ZAMAZENTA_HERO) { Item(ITEM_RUSTED_SHIELD); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + NOT MESSAGE("Wobbuffet knocked off the opposing Zamazenta's Rusted Shield!"); } } diff --git a/test/battle/move_effect/leech_seed.c b/test/battle/move_effect/leech_seed.c index fce80c661c57..67e829cf8ad4 100644 --- a/test/battle/move_effect/leech_seed.c +++ b/test/battle/move_effect/leech_seed.c @@ -20,8 +20,64 @@ SINGLE_BATTLE_TEST("Leech Seed doesn't affect Grass-type Pokémon") MESSAGE("It doesn't affect the opposing Oddish…"); } } + +SINGLE_BATTLE_TEST("Leech Seeded targets lose 1/8 of its max HP every turn and give it to the user") +{ + s16 damage; + s16 healed; + + GIVEN { + PLAYER(SPECIES_WYNAUT) { HP(1); } + OPPONENT(SPECIES_SHELLDER); + } WHEN { + TURN { MOVE(player, MOVE_LEECH_SEED); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); + HP_BAR(opponent); + HP_BAR(player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + } THEN { + EXPECT_MUL_EQ(damage, Q_4_12(-1), healed); + } +} + +SINGLE_BATTLE_TEST("Leech Seed recovery is prevented by Heal Block") +{ + GIVEN { + PLAYER(SPECIES_WYNAUT) { HP(1); } + OPPONENT(SPECIES_SHELLDER); + } WHEN { + TURN { MOVE(opponent, MOVE_HEAL_BLOCK); MOVE(player, MOVE_LEECH_SEED); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BLOCK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); + HP_BAR(opponent); + NOT HP_BAR(player); + } +} + +SINGLE_BATTLE_TEST("Leech Seed recovery will drain the hp of user if leech seeded mon has Liquid Ooze") +{ + s16 damage; + s16 healed; + + GIVEN { + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); } + } WHEN { + TURN { MOVE(player, MOVE_LEECH_SEED); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player); + HP_BAR(opponent, captureDamage: &damage); + HP_BAR(player, captureDamage: &healed); + } THEN { + EXPECT_EQ(damage, healed); + } +} + TO_DO_BATTLE_TEST("Leech Seed doesn't affect already seeded targets") -TO_DO_BATTLE_TEST("Leech Seeded targets lose 1/8 of its max HP every turn and give it to the user") TO_DO_BATTLE_TEST("Leech Seed's effect is paused until a new battler replaces the original user's position") // Faint, can't be replaced, then revived. TO_DO_BATTLE_TEST("Leech Seed's effect pause still prevents it from being seeded again") TO_DO_BATTLE_TEST("Baton Pass passes Leech Seed's effect"); diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 207544de1f84..dff486cb001e 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -103,7 +103,7 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging MESSAGE("Wobbuffet's Attack fell!"); #else MESSAGE("Wobbuffet's Attack harshly fell!"); - #endif + #endif } else if (statId == STAT_SPEED) { MESSAGE("Wobbuffet's Speed fell!"); } else if (statId == STAT_DEF) { @@ -487,36 +487,49 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves") } } -SINGLE_BATTLE_TEST("Protect does not block Confide") +SINGLE_BATTLE_TEST("Protect does not block Confide or Decorate") { + u32 move; + PARAMETRIZE { move = MOVE_CONFIDE; } + PARAMETRIZE { move = MOVE_DECORATE; } + GIVEN { ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(gMovesInfo[MOVE_CONFIDE].ignoresProtect == TRUE); + ASSUME(gMovesInfo[MOVE_DECORATE].effect == EFFECT_DECORATE); + ASSUME(gMovesInfo[MOVE_DECORATE].ignoresProtect == TRUE); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_CONFIDE); } + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, move); } } SCENE { - MESSAGE("Wobbuffet used Confide!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFIDE, player); + ANIMATION(ANIM_TYPE_MOVE, move, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); NOT MESSAGE("The opposing Wobbuffet protected itself!"); } } -DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide") +DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide and Decorate") { + u32 move; + PARAMETRIZE { move = MOVE_CONFIDE; } + PARAMETRIZE { move = MOVE_DECORATE; } + GIVEN { ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); + ASSUME(gMovesInfo[MOVE_CONFIDE].ignoresProtect == TRUE); + ASSUME(gMovesInfo[MOVE_DECORATE].effect == EFFECT_DECORATE); + ASSUME(gMovesInfo[MOVE_DECORATE].ignoresProtect == TRUE); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); } WHEN { - TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, MOVE_CONFIDE, target: opponentLeft); MOVE(playerRight, MOVE_CONFIDE, target: opponentRight); } + TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, move, target: opponentLeft); MOVE(playerRight, move, target: opponentRight); } } SCENE { - MESSAGE("Wobbuffet used Confide!"); + NOT ANIMATION(ANIM_TYPE_MOVE, move, playerLeft); MESSAGE("The opposing Wobbuffet protected itself!"); - MESSAGE("Wynaut used Confide!"); + NOT ANIMATION(ANIM_TYPE_MOVE, move, playerRight); MESSAGE("The opposing Wynaut protected itself!"); } } @@ -524,7 +537,6 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide") DOUBLE_BATTLE_TEST("Crafty Shield does not protect against moves that target all battlers") { GIVEN { - ASSUME(gMovesInfo[MOVE_FLOWER_SHIELD].target == MOVE_TARGET_ALL_BATTLERS); ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS); ASSUME(gSpeciesInfo[SPECIES_TANGROWTH].types[0] == TYPE_GRASS); ASSUME(gSpeciesInfo[SPECIES_SUNKERN].types[0] == TYPE_GRASS); @@ -570,3 +582,4 @@ SINGLE_BATTLE_TEST("Spiky Shield does not damage users on Counter or Mirror Coat } } } + diff --git a/test/battle/status2/confusion.c b/test/battle/status2/confusion.c index 96ed2e1362a0..4115123b3c11 100644 --- a/test/battle/status2/confusion.c +++ b/test/battle/status2/confusion.c @@ -26,3 +26,21 @@ SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power") EXPECT_EQ(damage[0], damage[1]); } } + +SINGLE_BATTLE_TEST("Confusion self hit does not consume Gems") +{ + PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION); + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_CONFUSE_RAY); MOVE(player, MOVE_TACKLE); } + } SCENE { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Normal Gem strengthened Wobbuffet's power!"); + } + MESSAGE("It hurt itself in its confusion!"); + } +} diff --git a/tools/trainerproc/main.c b/tools/trainerproc/main.c index b410e810b084..8b939a955f8e 100644 --- a/tools/trainerproc/main.c +++ b/tools/trainerproc/main.c @@ -1545,6 +1545,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s) static const unsigned char *male = (unsigned char *)u8"♂"; static const unsigned char *female = (unsigned char *)u8"♀"; static const unsigned char *e_diacritic = (unsigned char *)u8"é"; + static const unsigned char *right_single_quotation_mark = (unsigned char *)u8"’"; for (int i = 0; i < s.string_n; i++) { unsigned char c = s.string[i]; @@ -1562,7 +1563,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s) underscore = false; fputc(c - 'a' + 'A', f); } - else if (c == '\'' || c == '%') + else if (c == '\'' || c == '%' || is_utf8_character(s, &i, right_single_quotation_mark)) { // Do nothing. }