diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 4854df27c927..32498c8bfe09 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1934,6 +1934,12 @@ 1: .endm + .macro jumpifflowerveilattacker jumpptr:req + jumpifnottype BS_ATTACKER, TYPE_GRASS, 1f + jumpifability BS_ATTACKER_SIDE, ABILITY_FLOWER_VEIL, \jumpptr + 1: + .endm + .macro setallytonexttarget jumpptr:req jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f addbyte gBattlerTarget, 0x2 diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 809326be04c7..7c85e296c7fb 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -822,6 +822,7 @@ gBattleAnims_General:: .4byte General_SlideOffScreen @ B_ANIM_SLIDE_OFFSCREEN .4byte General_RestoreBg @ B_ANIM_RESTORE_BG .4byte General_TotemFlare @ B_ANIM_TOTEM_FLARE + .4byte General_GulpMissile @ B_ANIM_GULP_MISSILE .4byte General_ItemHealsHP @ B_ANIM_ITEM_HEAL .align 2 @@ -24412,6 +24413,20 @@ General_ItemHealsHP:: waitforvisualfinish end +General_GulpMissile: @ Tackle anim (placeholder) + loadspritegfx ANIM_TAG_IMPACT + monbg ANIM_ATTACKER + setalpha 12, 8 + createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4 + delay 6 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_ATTACKER, 2 + createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 3, 0, 6, 1 + playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET + waitforvisualfinish + clearmonbg ANIM_ATTACKER + blendoff + end + RainbowEndureEffect: launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2 delay 0x3 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 4535121ee26f..8ea11c11e7fa 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5969,6 +5969,76 @@ BattleScript_PerishBodyActivates:: orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 return +BattleScript_GulpMissileGorging:: + call BattleScript_AbilityPopUp + playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL + waitanimation + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 + effectivenesssound + hitanimation BS_ATTACKER + waitstate + jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGorging + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + tryfaintmon BS_ATTACKER, FALSE, NULL + getbattlerfainted BS_ATTACKER + jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGorging +BattleScript_GulpMissileNoDmgGorging: + handleformchange BS_TARGET, 0 + playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL + waitanimation + swapattackerwithtarget + setmoveeffect MOVE_EFFECT_PARALYSIS + seteffectprimary + swapattackerwithtarget + return +BattleScript_GulpMissileNoSecondEffectGorging: + handleformchange BS_TARGET, 0 + playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL + waitanimation + return + +BattleScript_GulpMissileGulping:: + call BattleScript_AbilityPopUp + playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL + waitanimation + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 + effectivenesssound + hitanimation BS_ATTACKER + waitstate + jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGulping + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + tryfaintmon BS_ATTACKER, FALSE, NULL + getbattlerfainted BS_ATTACKER + jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGulping + jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping + jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping + jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping + jumpifflowerveilattacker BattleScript_GulpMissileNoSecondEffectGulping +BattleScript_GulpMissileNoDmgGulping: + handleformchange BS_TARGET, 0 + playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL + waitanimation + swapattackerwithtarget @ to make gStatDownStringIds down below print the right battler + setstatchanger STAT_DEF, 1, TRUE + statbuffchange STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_GulpMissileGorgingTargetDefenseCantGoLower + setgraphicalstatchangevalues + playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatDownStringIds + waitmessage B_WAIT_TIME_LONG + swapattackerwithtarget @ restore the battlers, just in case + return +BattleScript_GulpMissileNoSecondEffectGulping: + handleformchange BS_TARGET, 0 + playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL + waitanimation + return +BattleScript_GulpMissileGorgingTargetDefenseCantGoLower: + printstring STRINGID_STATSWONTDECREASE + waitmessage B_WAIT_TIME_LONG + return + BattleScript_PerishSongCountGoesDown:: printstring STRINGID_PKMNPERISHCOUNTFELL waitmessage B_WAIT_TIME_LONG diff --git a/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc b/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc index d1157b7cb99c..ba73cfc1fdd4 100644 --- a/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc +++ b/data/maps/FallarborTown_MoveRelearnersHouse/scripts.inc @@ -104,7 +104,7 @@ FallarborTown_Text_AnnoyingIntroPart8: .string "Ivy: And for one Bottle Cap, I'll change\n" .string "one of a Pokémon's IVs to whatever\l" .string "you want.\p" - .string "Also, for five Caps, I'll change all\n" + .string "Also, for three Caps, I'll change all\n" .string "of a Pokémon's IVs to give them a new\l" .string "Hidden Power type.$" @@ -583,7 +583,7 @@ HyperTraining_EventScript_ChangeOneIV:: goto HyperTraining_EventScript_DoHyperTraining HyperTraining_EventScript_ChangeHiddenPower:: - msgbox HyperTraining_Text_ForFiveCapsChangeAllIVs, MSGBOX_DEFAULT + msgbox HyperTraining_Text_ForThreeCapsChangeAllIVs, MSGBOX_DEFAULT copyvar VAR_0x800A, VAR_0x8004 setvar VAR_0x8004, SCROLL_MULTI_HIDDEN_POWER special ShowScrollableMultichoice @@ -679,7 +679,7 @@ HyperTraining_EventScript_ChangeAllIVs:: compare VAR_RESULT, FALSE goto_if_eq HyperTraining_EventScript_NotEnoughCaps special ChangeChosenMonHiddenPower - msgbox HyperTraining_Text_PayFiveCaps, MSGBOX_DEFAULT + msgbox HyperTraining_Text_PayThreeCaps, MSGBOX_DEFAULT removeitem ITEM_BOTTLE_CAP, 3 goto HyperTraining_EventScript_DoHyperTraining @@ -714,15 +714,17 @@ HyperTraining_Text_WantMeExplainIVs: HyperTraining_Text_ExplainIVs: .string "Ivy: IVs are a hidden part of your\n" .string "Pokémon's stats that can only be\l" - .string "changed with special training.\p" + .string "changed with special training,\l" + .string "or raised by giving them Vitamins.\p" .string "They can be any value between\n" .string "0 and 31, and affect things like\l" .string "the type of the move Hidden Power.\p" .string "Higher IVs means higher stats, but\n" .string "higher stats aren't always better!\p" .string "Example: If your Pokémon relies on\n" - .string "Special Attacks, a low Attack IV may\l" - .string "help when it's confused in battle.$" + .string "Special Attacks, a low Attack IV will\l" + .string "reduce the damage it takes if it hits\l" + .string "itself in confusion.$" HyperTraining_Text_LetsTakeALook: .string "OK! Let's take a look at your\n" @@ -761,7 +763,7 @@ HyperTraining_Text_HyperTrainingMadeMonStronger: .string "stronger!\p" .string "Would you like to train some more?$" -HyperTraining_Text_ForFiveCapsChangeAllIVs: +HyperTraining_Text_ForThreeCapsChangeAllIVs: .string "For three Bottle Caps, I can change all\n" .string "of a Pokémon's IVs at once to give them\l" .string "a new Hidden Power type.\p" @@ -786,5 +788,5 @@ HyperTraining_Text_NotEnoughCaps: HyperTraining_Text_PayOneCap: .string "{PLAYER} handed over one Bottle Cap.$" -HyperTraining_Text_PayFiveCaps: - .string "{PLAYER} handed over five Bottle Caps.$" +HyperTraining_Text_PayThreeCaps: + .string "{PLAYER} handed over three Bottle Caps.$" diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 0d092529170d..2554c97e7378 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -387,6 +387,8 @@ extern const u8 BattleScript_TerrainPreventsEnd2[]; extern const u8 BattleScript_MistyTerrainPrevents[]; extern const u8 BattleScript_ElectricTerrainPrevents[]; extern const u8 BattleScript_DarkTypePreventsPrankster[]; +extern const u8 BattleScript_GulpMissileGorging[]; +extern const u8 BattleScript_GulpMissileGulping[]; extern const u8 BattleScript_MultiHitPrintStrings[]; extern const u8 BattleScript_BurnUpRemoveType[]; diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 89078308c42a..761aff43a69e 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -523,7 +523,8 @@ #define B_ANIM_SLIDE_OFFSCREEN 26 // for Emergency Exit #define B_ANIM_RESTORE_BG 27 // for Terrain Endings #define B_ANIM_TOTEM_FLARE 28 // Totem boosts aura flare -#define B_ANIM_ITEM_HEAL 29 // Leftovers and berries +#define B_ANIM_GULP_MISSILE 29 +#define B_ANIM_ITEM_HEAL 30 // Leftovers and berries // special animations table (gBattleAnims_Special) #define B_ANIM_LVL_UP 0 diff --git a/src/battle_anim.c b/src/battle_anim.c index 958fb4720858..d1a69bcde8e4 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -2213,6 +2213,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo case B_ANIM_DOOM_DESIRE_HIT: case B_ANIM_WISH_HEAL: case B_ANIM_MEGA_EVOLUTION: + case B_ANIM_GULP_MISSILE: hideHpBoxes = TRUE; break; default: diff --git a/src/battle_main.c b/src/battle_main.c index 817709dd7155..f09e4b5a2491 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3580,10 +3580,13 @@ static void TryDoEventsBeforeFirstTurn(void) return; // Set invalid mons as absent(for example when starting a double battle with only one pokemon). - for (i = 0; i < gBattlersCount; i++) + if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) { - if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE) - gAbsentBattlerFlags |= gBitTable[i]; + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE) + gAbsentBattlerFlags |= gBitTable[i]; + } } if (gBattleStruct->switchInAbilitiesCounter == 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index da0aa0d05d7f..b7478df0b547 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4839,7 +4839,8 @@ static void Cmd_moveend(void) case MOVEEND_RECOIL: if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) - && IsBattlerAlive(gBattlerAttacker)) + && IsBattlerAlive(gBattlerAttacker) + && gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one { switch (gBattleMoves[gCurrentMove].effect) { diff --git a/src/battle_util.c b/src/battle_util.c index be44668c7705..f74bd6b9db68 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3859,6 +3859,8 @@ static bool32 ShouldChangeFormHpBased(u32 battler) {ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, 2}, {ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, 2}, {ABILITY_SCHOOLING, SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, 4}, + {ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GORGING, 2}, + {ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GULPING, 1}, }; u32 i; @@ -5111,6 +5113,42 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_GULP_MISSILE: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && !gProtectStructs[gBattlerAttacker].confusionSelfDmg + && TARGET_TURN_DAMAGED + && IsBattlerAlive(battler)) + { + if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING) + { + gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species; + gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT; + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) + { + gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_GulpMissileGorging; + effect++; + } + else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING) + { + gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species; + gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT; + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) + { + gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_GulpMissileGulping; + effect++; + } + } + break; } break; case ABILITYEFFECT_MOVE_END_ATTACKER: // Same as above, but for attacker @@ -5148,6 +5186,15 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move effect++; } break; + case ABILITY_GULP_MISSILE: + if (((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER) + && (effect = ShouldChangeFormHpBased(gBattlerAttacker))) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AttackerFormChange; + effect++; + } + break; } break; case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis @@ -8943,6 +8990,8 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) {SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET}, {SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW}, {SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI}, + {SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT}, + {SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT}, }; if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out diff --git a/src/strings.c b/src/strings.c index 9e0a05d9eb26..a06f8bbd4d16 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1667,7 +1667,7 @@ const u8 gText_SavingNormalMode[] = _("Normal Mode"); const u8 gText_SavingHardMode[] = _("Hard Mode"); const u8 gText_SavingChallengeMode[] = _("Challenge Mode"); const u8 gText_SavingInsanityMode[] = _("Insanity Mode"); -const u8 gText_SavingVersionNum[] = _("Ver 1.7"); +const u8 gText_SavingVersionNum[] = _("Ver 1.7.1"); const u8 gText_WirelessCommStatus[] = _("Wireless Communication Status"); const u8 gText_PeopleTrading[] = _("People trading:"); const u8 gText_PeopleBattling[] = _("People battling:");