fix various issues with primal weather blocking water/fire type moves (#3138)

* fix various issues with primal weather blocking water/fire type moves

* forgot to change return to effect=1

* fix bugs
This commit is contained in:
DizzyEggg 2023-07-30 16:50:51 +02:00 committed by GitHub
parent 8196bea2d7
commit 5eec3b2fc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 164 additions and 42 deletions

View File

@ -8782,15 +8782,14 @@ BattleScript_DesolateLandActivates::
call BattleScript_ActivateWeatherAbilities call BattleScript_ActivateWeatherAbilities
end3 end3
BattleScript_DesolateLandEvaporatesWaterTypeMoves:: BattleScript_PrimalWeatherBlocksMove::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_ATTACKSTRING_PRINTED, BattleScript_MoveEnd @in case of multi-target moves, if move fails once, no point in printing the message twice
accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON
attackstring attackstring
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
ppreduce ppreduce
jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_STRING_PRINTED, BattleScript_MoveEnd printfromtable gPrimalWeatherBlocksStringIds
printstring STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_STRING_PRINTED
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_PrimordialSeaActivates:: BattleScript_PrimordialSeaActivates::
@ -8802,17 +8801,6 @@ BattleScript_PrimordialSeaActivates::
call BattleScript_ActivateWeatherAbilities call BattleScript_ActivateWeatherAbilities
end3 end3
BattleScript_PrimordialSeaFizzlesOutFireTypeMoves::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_STRING_PRINTED, BattleScript_MoveEnd
printstring STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_STRING_PRINTED
goto BattleScript_MoveEnd
BattleScript_DeltaStreamActivates:: BattleScript_DeltaStreamActivates::
pause B_WAIT_TIME_SHORT pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp

View File

@ -409,9 +409,8 @@ extern const u8 BattleScript_GulpMissileGorging[];
extern const u8 BattleScript_GulpMissileGulping[]; extern const u8 BattleScript_GulpMissileGulping[];
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[]; extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
extern const u8 BattleScript_DesolateLandActivates[]; extern const u8 BattleScript_DesolateLandActivates[];
extern const u8 BattleScript_DesolateLandEvaporatesWaterTypeMoves[];
extern const u8 BattleScript_PrimordialSeaActivates[]; extern const u8 BattleScript_PrimordialSeaActivates[];
extern const u8 BattleScript_PrimordialSeaFizzlesOutFireTypeMoves[]; extern const u8 BattleScript_PrimalWeatherBlocksMove[];
extern const u8 BattleScript_DeltaStreamActivates[]; extern const u8 BattleScript_DeltaStreamActivates[];
extern const u8 BattleScript_MysteriousAirCurrentBlowsOn[]; extern const u8 BattleScript_MysteriousAirCurrentBlowsOn[];
extern const u8 BattleScript_AttackWeakenedByStrongWinds[]; extern const u8 BattleScript_AttackWeakenedByStrongWinds[];

View File

@ -136,8 +136,8 @@ u8 DoBattlerEndTurnEffects(void);
bool8 HandleWishPerishSongOnTurnEnd(void); bool8 HandleWishPerishSongOnTurnEnd(void);
bool8 HandleFaintedMonActions(void); bool8 HandleFaintedMonActions(void);
void TryClearRageAndFuryCutter(void); void TryClearRageAndFuryCutter(void);
u8 AtkCanceller_UnableToUseMove(u32 moveType);
void SetAtkCancellerForCalledMove(void); void SetAtkCancellerForCalledMove(void);
u8 AtkCanceller_UnableToUseMove(void);
u8 AtkCanceller_UnableToUseMove2(void); u8 AtkCanceller_UnableToUseMove2(void);
bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2); bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2);
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility); bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);

View File

@ -827,6 +827,10 @@
#define B_MSG_SOMEONES_BOX_FULL 2 #define B_MSG_SOMEONES_BOX_FULL 2
#define B_MSG_LANETTES_BOX_FULL 3 #define B_MSG_LANETTES_BOX_FULL 3
// gPrimalWeatherBlocksStringIds
#define B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN 0
#define B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN 1
// gInobedientStringIds // gInobedientStringIds
#define B_MSG_LOAFING 0 #define B_MSG_LOAFING 0
#define B_MSG_WONT_OBEY 1 #define B_MSG_WONT_OBEY 1

View File

@ -1850,6 +1850,12 @@ const u16 gWeatherStartsStringIds[] =
[WEATHER_ABNORMAL] = STRINGID_ITISRAINING [WEATHER_ABNORMAL] = STRINGID_ITISRAINING
}; };
const u16 gPrimalWeatherBlocksStringIds[] =
{
[B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN] = STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN,
[B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN] = STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT,
};
const u16 gInobedientStringIds[] = const u16 gInobedientStringIds[] =
{ {
[B_MSG_LOAFING] = STRINGID_PKMNLOAFING, [B_MSG_LOAFING] = STRINGID_PKMNLOAFING,

View File

@ -1503,25 +1503,8 @@ static void Cmd_attackcanceler(void)
s32 i, moveType; s32 i, moveType;
u16 attackerAbility = GetBattlerAbility(gBattlerAttacker); u16 attackerAbility = GetBattlerAbility(gBattlerAttacker);
GET_MOVE_TYPE(gCurrentMove, moveType); GET_MOVE_TYPE(gCurrentMove, moveType);
if (WEATHER_HAS_EFFECT && gBattleMoves[gCurrentMove].power)
{
if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrimordialSeaFizzlesOutFireTypeMoves;
return;
}
else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL))
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DesolateLandEvaporatesWaterTypeMoves;
return;
}
}
if (gBattleOutcome != 0) if (gBattleOutcome != 0)
{ {
gCurrentActionFuncId = B_ACTION_FINISHED; gCurrentActionFuncId = B_ACTION_FINISHED;
@ -1537,9 +1520,27 @@ static void Cmd_attackcanceler(void)
if (TryAegiFormChange()) if (TryAegiFormChange())
return; return;
#endif #endif
if (AtkCanceller_UnableToUseMove()) if (AtkCanceller_UnableToUseMove(moveType))
return; return;
if (WEATHER_HAS_EFFECT && gBattleMoves[gCurrentMove].power)
{
if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
return;
}
else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
return;
}
}
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND && GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
&& IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker) && IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker)

View File

@ -3389,10 +3389,9 @@ void SetAtkCancellerForCalledMove(void)
gBattleStruct->isAtkCancelerForCalledMove = TRUE; gBattleStruct->isAtkCancelerForCalledMove = TRUE;
} }
u8 AtkCanceller_UnableToUseMove(void) u8 AtkCanceller_UnableToUseMove(u32 moveType)
{ {
u8 effect = 0; u8 effect = 0;
s32 *bideDmg = &gBattleScripting.bideDmg;
do do
{ {
switch (gBattleStruct->atkCancellerTracker) switch (gBattleStruct->atkCancellerTracker)
@ -3653,7 +3652,7 @@ u8 AtkCanceller_UnableToUseMove(void)
if (gTakenDmg[gBattlerAttacker]) if (gTakenDmg[gBattlerAttacker])
{ {
gCurrentMove = MOVE_BIDE; gCurrentMove = MOVE_BIDE;
*bideDmg = gTakenDmg[gBattlerAttacker] * 2; gBattleScripting.bideDmg = gTakenDmg[gBattlerAttacker] * 2;
gBattlerTarget = gTakenDmgByBattler[gBattlerAttacker]; gBattlerTarget = gTakenDmgByBattler[gBattlerAttacker];
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
gBattlerTarget = GetMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1); gBattlerTarget = GetMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1);
@ -3723,8 +3722,6 @@ u8 AtkCanceller_UnableToUseMove(void)
case CANCELLER_POWDER_STATUS: case CANCELLER_POWDER_STATUS:
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER) if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER)
{ {
u32 moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
if (moveType == TYPE_FIRE) if (moveType == TYPE_FIRE)
{ {
gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE; gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE;

127
test/primal_weather.c Normal file
View File

@ -0,0 +1,127 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_EMBER].power != 0);
ASSUME(gBattleMoves[MOVE_EMBER].type == TYPE_FIRE);
ASSUME(gBattleMoves[MOVE_WATER_GUN].power != 0);
ASSUME(gBattleMoves[MOVE_WATER_GUN].type == TYPE_WATER);
}
SINGLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves")
{
GIVEN {
PLAYER(SPECIES_KYOGRE) {Item(ITEM_BLUE_ORB);}
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_EMBER); }
TURN { MOVE(opponent, MOVE_EMBER); }
} SCENE {
MESSAGE("Foe Wobbuffet used Ember!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
MESSAGE("The Fire-type attack fizzled out\nin the heavy rain!");
NOT HP_BAR(player);
MESSAGE("Foe Wobbuffet used Ember!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, opponent);
MESSAGE("The Fire-type attack fizzled out\nin the heavy rain!");
NOT HP_BAR(player);
} THEN {
EXPECT_EQ(player->hp, player->maxHP);
}
}
DOUBLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves and prints the message only once with moves hitting multiple targets")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_ERUPTION].power != 0);
ASSUME(gBattleMoves[MOVE_ERUPTION].type == TYPE_FIRE);
ASSUME(gBattleMoves[MOVE_ERUPTION].target == MOVE_TARGET_BOTH);
PLAYER(SPECIES_KYOGRE) {Item(ITEM_BLUE_ORB); {Speed(5);}}
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(10);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(8);}
} WHEN {
TURN { MOVE(opponentLeft, MOVE_ERUPTION); }
} SCENE {
MESSAGE("Foe Wobbuffet used Eruption!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_ERUPTION, opponentLeft);
MESSAGE("The Fire-type attack fizzled out\nin the heavy rain!");
NOT MESSAGE("The Fire-type attack fizzled out\nin the heavy rain!");
} THEN {
EXPECT_EQ(playerLeft->hp, playerLeft->maxHP);
EXPECT_EQ(playerRight->hp, playerRight->maxHP);
}
}
SINGLE_BATTLE_TEST("Primordial Sea does not block a move if pokemon is asleep and uses a Fire-type move") // Sleep/confusion/paralysis all happen before the check for primal weather
{
GIVEN {
PLAYER(SPECIES_KYOGRE) {Item(ITEM_BLUE_ORB);}
OPPONENT(SPECIES_WOBBUFFET) {Status1(STATUS1_SLEEP);}
} WHEN {
TURN { MOVE(opponent, MOVE_EMBER); }
} SCENE {
NOT MESSAGE("The Fire-type attack fizzled out\nin the heavy rain!");
MESSAGE("Foe Wobbuffet is fast asleep.");
}
}
SINGLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves")
{
GIVEN {
PLAYER(SPECIES_GROUDON) {Item(ITEM_RED_ORB);}
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_WATER_GUN); }
TURN { MOVE(opponent, MOVE_WATER_GUN); }
} SCENE {
MESSAGE("Foe Wobbuffet used Water Gun!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
MESSAGE("The Water-type attack evaporated in the harsh sunlight!");
NOT HP_BAR(player);
MESSAGE("Foe Wobbuffet used Water Gun!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, opponent);
MESSAGE("The Water-type attack evaporated in the harsh sunlight!");
NOT HP_BAR(player);
} THEN {
EXPECT_EQ(player->hp, player->maxHP);
}
}
DOUBLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves and prints the message only once with moves hitting multiple targets")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_SURF].power != 0);
ASSUME(gBattleMoves[MOVE_SURF].type == TYPE_WATER);
ASSUME(gBattleMoves[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_GROUDON) {Item(ITEM_RED_ORB); {Speed(5);}}
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(10);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(8);}
} WHEN {
TURN { MOVE(opponentLeft, MOVE_SURF); }
} SCENE {
MESSAGE("Foe Wobbuffet used Surf!");
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentLeft);
MESSAGE("The Water-type attack evaporated in the harsh sunlight!");
NOT MESSAGE("The Water-type attack evaporated in the harsh sunlight!");
} THEN {
EXPECT_EQ(playerLeft->hp, playerLeft->maxHP);
EXPECT_EQ(playerRight->hp, playerRight->maxHP);
EXPECT_EQ(opponentRight->hp, opponentRight->maxHP);
}
}
SINGLE_BATTLE_TEST("Desolate Land does not block a move if pokemon is asleep and uses a Water-type move") // Sleep/confusion/paralysis all happen before the check for primal weather
{
GIVEN {
PLAYER(SPECIES_GROUDON) {Item(ITEM_RED_ORB);}
OPPONENT(SPECIES_WOBBUFFET) {Status1(STATUS1_SLEEP);}
} WHEN {
TURN { MOVE(opponent, MOVE_WATER_GUN); }
} SCENE {
NOT MESSAGE("The Water-type attack evaporated in the harsh sunlight!");
MESSAGE("Foe Wobbuffet is fast asleep.");
}
}