diff --git a/include/battle_controllers.h b/include/battle_controllers.h index 1cedf81fa4..71ca640976 100644 --- a/include/battle_controllers.h +++ b/include/battle_controllers.h @@ -185,6 +185,7 @@ extern struct UnusedControllerStruct gUnusedControllerStruct; void HandleLinkBattleSetup(void); void SetUpBattleVarsAndBirchZigzagoon(void); void InitBattleControllers(void); +bool32 IsValidForBattle(struct Pokemon *mon); void TryReceiveLinkBattleData(void); void PrepareBufferDataTransferLink(u8 bufferId, u16 size, u8 *data); diff --git a/include/battle_util.h b/include/battle_util.h index ba51c9d241..8453d95a56 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -151,6 +151,7 @@ void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast); bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind); bool32 TryRoomService(u8 battlerId); void BufferStatChange(u8 battlerId, u8 statId, u8 stringId); +void DoBurmyFormChange(u32 monId); // ability checks bool32 IsRolePlayBannedAbilityAtk(u16 ability); diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index edf1cbb4fb..b2559dbb7f 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -37,6 +37,9 @@ #define SPECIES_ZYGARDE 0 // 50% #define SPECIES_ZYGARDE_10 10011 // 10 % #define SPECIES_ZYGARDE_COMPLETE 10012 // 100 % + #define SPECIES_BURMY 0 + #define SPECIES_BURMY_SANDY_CLOAK 10013 + #define SPECIES_BURMY_TRASH_CLOAK 10014 #endif // Items with peculiar battle effects. diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 2698956d69..b43e80225b 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -225,12 +225,18 @@ static void Intro_DelayAndEnd(void) } } +static bool32 TwoIntroMons(u32 battlerId) // Double battle with both player pokemon active. +{ + return (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[battlerId ^ BIT_FLANK]])); +} + static void Intro_WaitForShinyAnimAndHealthbox(void) { bool8 healthboxAnimDone = FALSE; bool8 twoMons; - if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))) + twoMons = TwoIntroMons(gActiveBattler); + if (!twoMons || ((twoMons && (gBattleTypeFlags & BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))) { if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; @@ -292,15 +298,17 @@ static void Intro_TryShinyAnimShowHealthbox(void) { bool32 bgmRestored = FALSE; bool32 battlerAnimsDone = FALSE; + bool32 twoMons; if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + twoMons = TwoIntroMons(gActiveBattler); if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT) - && IsDoubleBattle() + && twoMons && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].finishedShinyMonAnim) @@ -310,7 +318,7 @@ static void Intro_TryShinyAnimShowHealthbox(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) { - if (IsDoubleBattle() && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) + if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) { UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL); StartHealthboxSlideIn(gActiveBattler ^ BIT_FLANK); @@ -342,7 +350,7 @@ static void Intro_TryShinyAnimShowHealthbox(void) bgmRestored = TRUE; } - if (!IsDoubleBattle() || (IsDoubleBattle() && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT)) + if (!twoMons || (twoMons && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT)) { if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) @@ -363,7 +371,7 @@ static void Intro_TryShinyAnimShowHealthbox(void) if (bgmRestored && battlerAnimsDone) { - if (IsDoubleBattle() && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) + if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) { DestroySprite(&gSprites[gBattleControllerData[gActiveBattler ^ BIT_FLANK]]); SetBattlerShadowSpriteCallback(gActiveBattler ^ BIT_FLANK, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], MON_DATA_SPECIES)); @@ -469,7 +477,7 @@ static void SwitchIn_HandleSoundAndEnd(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy + if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy || gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) { m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100); @@ -1892,7 +1900,7 @@ static void Task_StartSendOutAnim(u8 taskId) u8 savedActiveBank = gActiveBattler; gActiveBattler = gTasks[taskId].data[0]; - if ((!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT) + if ((!TwoIntroMons(gActiveBattler) || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT) { gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; StartSendOutAnim(gActiveBattler, FALSE); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 841e303270..a9e85861cb 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1034,20 +1034,25 @@ static void Intro_DelayAndEnd(void) } } +static bool32 TwoIntroMons(u32 battlerId) // Double battle with both player pokemon active. +{ + return (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[battlerId ^ BIT_FLANK]])); +} + static void Intro_WaitForShinyAnimAndHealthbox(void) { bool8 healthboxAnimDone = FALSE; // Check if healthbox has finished sliding in - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } @@ -1065,7 +1070,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(void) HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - if (IsDoubleBattle()) + if (TwoIntroMons(gActiveBattler)) HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], gActiveBattler ^ BIT_FLANK); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; @@ -1094,7 +1099,7 @@ static void Intro_TryShinyAnimShowHealthbox(void) { if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) { - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL); StartHealthboxSlideIn(gActiveBattler ^ BIT_FLANK); @@ -1125,15 +1130,7 @@ static void Intro_TryShinyAnimShowHealthbox(void) } // Wait for battler anims - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) - { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - battlerAnimsDone = TRUE; - } - } - else + if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy @@ -1143,11 +1140,19 @@ static void Intro_TryShinyAnimShowHealthbox(void) battlerAnimsDone = TRUE; } } + else + { + if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + battlerAnimsDone = TRUE; + } + } // Clean up if (bgmRestored && battlerAnimsDone) { - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) DestroySprite(&gSprites[gBattleControllerData[gActiveBattler ^ BIT_FLANK]]); DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); @@ -3114,12 +3119,7 @@ static void Task_StartSendOutAnim(u8 taskId) u8 savedActiveBattler = gActiveBattler; gActiveBattler = gTasks[taskId].tBattlerId; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else + if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; StartSendOutAnim(gActiveBattler, FALSE); @@ -3129,6 +3129,11 @@ static void Task_StartSendOutAnim(u8 taskId) StartSendOutAnim(gActiveBattler, FALSE); gActiveBattler ^= BIT_FLANK; } + else + { + gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + StartSendOutAnim(gActiveBattler, FALSE); + } gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; gActiveBattler = savedActiveBattler; DestroyTask(taskId); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 2fc7cac075..033a121228 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -588,6 +588,14 @@ static void InitLinkBtlControllers(void) } } +bool32 IsValidForBattle(struct Pokemon *mon) +{ + u32 species = GetMonData(mon, MON_DATA_SPECIES2); + return (species != SPECIES_NONE && species != SPECIES_EGG + && GetMonData(mon, MON_DATA_HP) != 0 + && GetMonData(mon, MON_DATA_IS_EGG) == 0); +} + static void SetBattlePartyIds(void) { s32 i, j; @@ -602,10 +610,7 @@ static void SetBattlePartyIds(void) { if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER) { - if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0 - && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG - && GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0) + if (IsValidForBattle(&gPlayerParty[j])) { gBattlerPartyIndexes[i] = j; break; @@ -613,10 +618,7 @@ static void SetBattlePartyIds(void) } else { - if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0 - && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG - && GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0) + if (IsValidForBattle(&gEnemyParty[j])) { gBattlerPartyIndexes[i] = j; break; @@ -627,11 +629,7 @@ static void SetBattlePartyIds(void) { if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER) { - if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0 - && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES) != SPECIES_NONE // Probably a typo by Game Freak. The rest use SPECIES2. - && GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG - && GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0 - && gBattlerPartyIndexes[i - 2] != j) + if (IsValidForBattle(&gPlayerParty[j]) && gBattlerPartyIndexes[i - 2] != j) { gBattlerPartyIndexes[i] = j; break; @@ -639,16 +637,18 @@ static void SetBattlePartyIds(void) } else { - if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0 - && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG - && GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0 - && gBattlerPartyIndexes[i - 2] != j) + if (IsValidForBattle(&gEnemyParty[j]) && gBattlerPartyIndexes[i - 2] != j) { gBattlerPartyIndexes[i] = j; break; } } + + // No valid mons were found. Add the empty slot. + if (gBattlerPartyIndexes[i - 2] == 0) + gBattlerPartyIndexes[i] = 1; + else + gBattlerPartyIndexes[i] = 0; } } } diff --git a/src/battle_main.c b/src/battle_main.c index 0780c88021..e7139e0d14 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3463,6 +3463,13 @@ static void TryDoEventsBeforeFirstTurn(void) if (gBattleControllerExecFlags) return; + // Set invalid mons as absent(for example when starting a double battle with only one pokemon). + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE) + gAbsentBattlerFlags |= gBitTable[i]; + } + if (gBattleStruct->switchInAbilitiesCounter == 0) { for (i = 0; i < gBattlersCount; i++) @@ -4089,10 +4096,10 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_ACTION_CONFIRMED_STANDBY: - if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) + if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) - | (gBitTable[gActiveBattler] << 4) - | (gBitTable[gActiveBattler] << 8) + | (gBitTable[gActiveBattler] << 4) + | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12)))) { if (AllAtActionConfirmed()) @@ -4659,7 +4666,7 @@ static void CheckQuickClaw_CustapBerryActivation(void) } } } - + // setup stuff before turns/actions TryClearRageAndFuryCutter(); gCurrentTurnActionNumber = 0; @@ -4896,6 +4903,7 @@ static void HandleEndTurn_FinishBattle(void) { UndoMegaEvolution(i); UndoFormChange(i, B_SIDE_PLAYER, FALSE); + DoBurmyFormChange(i); } gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions; gCB2_AfterEvolution = BattleMainCB2; diff --git a/src/battle_message.c b/src/battle_message.c index 6539a159b2..ab10ceff06 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -2584,7 +2584,7 @@ void BufferStringBattle(u16 stringID) { if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) stringPtr = sText_LegendaryPkmnAppeared; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]])) // interesting, looks like they had something planned for wild double battles stringPtr = sText_TwoWildPkmnAppeared; else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) stringPtr = sText_WildPkmnAppearedPause; @@ -2595,7 +2595,7 @@ void BufferStringBattle(u16 stringID) case STRINGID_INTROSENDOUT: // poke first send-out if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]])) { if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) stringPtr = sText_InGamePartnerSentOutZGoN; @@ -2613,7 +2613,7 @@ void BufferStringBattle(u16 stringID) } else { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]])) { if (BATTLE_TWO_VS_ONE_OPPONENT) stringPtr = sText_Trainer1SentOutTwoPkmn; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 313d3ea460..ea9278f45f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11439,7 +11439,7 @@ static void Cmd_setcharge(void) static void Cmd_callterrainattack(void) // nature power { gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = sNaturePowerMoves[gBattleTerrain]; + gCurrentMove = GetNaturePowerMove(); gBattlerTarget = GetMoveTarget(gCurrentMove, 0); BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); gBattlescriptCurrInstr++; @@ -11447,7 +11447,14 @@ static void Cmd_callterrainattack(void) // nature power u16 GetNaturePowerMove(void) { - //TODO terrain + if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + return MOVE_MOONBLAST; + else if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + return MOVE_THUNDERBOLT; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + return MOVE_ENERGY_BALL; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + return MOVE_PSYCHIC; return sNaturePowerMoves[gBattleTerrain]; } diff --git a/src/battle_util.c b/src/battle_util.c index 16adcda754..6eb6556363 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8397,16 +8397,18 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat modifier = UQ_4_12(1.0); } - if (GetBattlerAbility(battlerDef) == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0) && gBattleMoves[move].power) + if (((GetBattlerAbility(battlerDef) == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0)) + || (GetBattlerAbility(battlerDef) == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk))) + && gBattleMoves[move].power) { modifier = UQ_4_12(0.0); if (recordAbilities) { - gLastUsedAbility = ABILITY_WONDER_GUARD; + gLastUsedAbility = gBattleMons[battlerDef].ability; gMoveResultFlags |= MOVE_RESULT_MISSED; gLastLandedMoves[battlerDef] = 0; gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_DMG; - RecordAbilityBattle(battlerDef, ABILITY_WONDER_GUARD); + RecordAbilityBattle(battlerDef, gBattleMons[battlerDef].ability); } } @@ -9186,3 +9188,43 @@ bool32 TryRoomService(u8 battlerId) return FALSE; } } + +void DoBurmyFormChange(u32 monId) +{ + u16 newSpecies, currSpecies; + s32 sentIn; + struct Pokemon *party = gPlayerParty; + + sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1]; + currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL); + + if ((GET_BASE_SPECIES_ID(currSpecies) == SPECIES_BURMY) && (gBitTable[monId] & sentIn)) + { + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + case BATTLE_TERRAIN_LONG_GRASS: + case BATTLE_TERRAIN_POND: + case BATTLE_TERRAIN_MOUNTAIN: + case BATTLE_TERRAIN_PLAIN: + newSpecies = SPECIES_BURMY; + break; + case BATTLE_TERRAIN_CAVE: + case BATTLE_TERRAIN_SAND: + newSpecies = SPECIES_BURMY_SANDY_CLOAK; + break; + case BATTLE_TERRAIN_BUILDING: + newSpecies = SPECIES_BURMY_TRASH_CLOAK; + break; + default: // Don't change form if last battle was water-related + newSpecies = SPECIES_NONE; + break; + } + + if (newSpecies != SPECIES_NONE) + { + SetMonData(&party[monId], MON_DATA_SPECIES, &newSpecies); + CalculateMonStats(&party[monId]); + } + } +} diff --git a/src/pokedex.c b/src/pokedex.c index cc469b32f8..9de5e0c744 100644 --- a/src/pokedex.c +++ b/src/pokedex.c @@ -1393,6 +1393,7 @@ static const struct SearchOptionText sDexSearchTypeOptions[NUMBER_OF_MON_TYPES + {gText_DexEmptyString, gTypeNames[TYPE_ICE]}, {gText_DexEmptyString, gTypeNames[TYPE_DRAGON]}, {gText_DexEmptyString, gTypeNames[TYPE_DARK]}, + {gText_DexEmptyString, gTypeNames[TYPE_FAIRY]}, {}, }; @@ -1427,6 +1428,7 @@ static const u8 sDexSearchTypeIds[NUMBER_OF_MON_TYPES] = TYPE_ICE, TYPE_DRAGON, TYPE_DARK, + TYPE_FAIRY, }; // Number pairs are the task data for tracking the cursor pos and scroll offset of each option list