Fixes Protosynthesis not activating after weather was reset (#8021)

This commit is contained in:
Alex 2025-10-24 18:53:34 +02:00 committed by GitHub
parent 8e76889579
commit 8ea947d5a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 43 deletions

View File

@ -242,7 +242,8 @@ void TryClearRageAndFuryCutter(void);
enum MoveCanceller AtkCanceller_MoveSuccessOrder(void);
void SetAtkCancellerForCalledMove(void);
bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility);
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability);
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag);
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, u32 move, enum FunctionCallOption option);
bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 move, u32 moveType, enum FunctionCallOption option);
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);

View File

@ -3831,7 +3831,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
}
break;
}
if (TryChangeBattleWeather(gBattlerAttacker, weather, FALSE))
if (TryChangeBattleWeather(gBattlerAttacker, weather, ABILITY_NONE))
{
gBattleCommunication[MULTISTRING_CHOOSER] = msg;
BattleScriptPush(gBattlescriptCurrInstr + 1);
@ -9744,7 +9744,7 @@ static void Cmd_setfieldweather(void)
u8 battleWeatherId = cmd->weather;
if (!TryChangeBattleWeather(gBattlerAttacker, battleWeatherId, FALSE))
if (!TryChangeBattleWeather(gBattlerAttacker, battleWeatherId, ABILITY_NONE))
{
gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_FAILED;
@ -15338,12 +15338,13 @@ void BS_SetTerrain(void)
default:
break;
}
if (statusFlag)
if (gBattleStruct->isSkyBattle)
{
enum ItemHoldEffect atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
gFieldTimers.terrainTimer = gBattleTurnCounter + ((atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5);
gBattlescriptCurrInstr = cmd->jumpInstr;
}
else if (statusFlag)
{
TryChangeBattleTerrain(gBattlerAttacker, statusFlag);
gBattlescriptCurrInstr = cmd->nextInstr;
}
else

View File

@ -2791,24 +2791,24 @@ bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2
}
}
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility)
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, u32 ability)
{
u16 battlerAbility = GetBattlerAbility(battler);
if (gBattleWeather & sBattleWeatherInfo[battleWeatherId].flag)
{
return FALSE;
}
else if (gBattleWeather & B_WEATHER_PRIMAL_ANY
&& battlerAbility != ABILITY_DESOLATE_LAND
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
&& battlerAbility != ABILITY_DELTA_STREAM)
&& ability != ABILITY_DESOLATE_LAND
&& ability != ABILITY_PRIMORDIAL_SEA
&& ability != ABILITY_DELTA_STREAM)
{
return FALSE;
}
else if (GetGenConfig(GEN_CONFIG_ABILITY_WEATHER) < GEN_6 && viaAbility)
else if (GetGenConfig(GEN_CONFIG_ABILITY_WEATHER) < GEN_6 && ability != ABILITY_NONE)
{
gBattleWeather = sBattleWeatherInfo[battleWeatherId].flag;
for (u32 i = 0; i < gBattlersCount; i++)
gDisableStructs[i].weatherAbilityDone = FALSE;
return TRUE;
}
else
@ -2821,25 +2821,29 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbilit
gWishFutureKnock.weatherDuration = 8;
else
gWishFutureKnock.weatherDuration = 5;
for (u32 i = 0; i < gBattlersCount; i++)
gDisableStructs[i].weatherAbilityDone = FALSE;
return TRUE;
}
return FALSE;
}
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u16 *timer)
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag)
{
if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
if (gBattleStruct->isSkyBattle)
return FALSE;
if (!(gFieldStatuses & statusFlag))
{
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
gDisableStructs[battler].terrainAbilityDone = FALSE;
for (u32 i = 0; i < gBattlersCount; i++)
gDisableStructs[i].terrainAbilityDone = FALSE;
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
*timer = gBattleTurnCounter + 8;
gFieldTimers.terrainTimer = gBattleTurnCounter + 8;
else
*timer = gBattleTurnCounter + 5;
gFieldTimers.terrainTimer = gBattleTurnCounter + 5;
gBattleScripting.battler = battler;
return TRUE;
}
@ -3838,7 +3842,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_DRIZZLE:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
effect++;
@ -3851,7 +3855,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_SAND_STREAM:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
effect++;
@ -3863,8 +3867,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
effect++;
}
break;
case ABILITY_ORICHALCUM_PULSE:
case ABILITY_DROUGHT:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
effect++;
@ -3877,12 +3882,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_SNOW_WARNING:
if (GetGenConfig(GEN_SNOW_WARNING) >= GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_SNOW, TRUE))
if (GetGenConfig(GEN_SNOW_WARNING) >= GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_SNOW, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesSnow);
effect++;
}
else if (GetGenConfig(GEN_SNOW_WARNING) < GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_HAIL, TRUE))
else if (GetGenConfig(GEN_SNOW_WARNING) < GEN_9 && TryChangeBattleWeather(battler, BATTLE_WEATHER_HAIL, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivatesHail);
effect++;
@ -3896,28 +3901,28 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_ELECTRIC_SURGE:
case ABILITY_HADRON_ENGINE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.terrainTimer))
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN))
{
BattleScriptPushCursorAndCallback(BattleScript_ElectricSurgeActivates);
effect++;
}
break;
case ABILITY_GRASSY_SURGE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
if (TryChangeBattleTerrain(battler, STATUS_FIELD_GRASSY_TERRAIN))
{
BattleScriptPushCursorAndCallback(BattleScript_GrassySurgeActivates);
effect++;
}
break;
case ABILITY_MISTY_SURGE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN, &gFieldTimers.terrainTimer))
if (TryChangeBattleTerrain(battler, STATUS_FIELD_MISTY_TERRAIN))
{
BattleScriptPushCursorAndCallback(BattleScript_MistySurgeActivates);
effect++;
}
break;
case ABILITY_PSYCHIC_SURGE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN, &gFieldTimers.terrainTimer))
if (TryChangeBattleTerrain(battler, STATUS_FIELD_PSYCHIC_TERRAIN))
{
BattleScriptPushCursorAndCallback(BattleScript_PsychicSurgeActivates);
effect++;
@ -4018,21 +4023,21 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_DESOLATE_LAND:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN_PRIMAL, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN_PRIMAL, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_DesolateLandActivates);
effect++;
}
break;
case ABILITY_PRIMORDIAL_SEA:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN_PRIMAL, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_RAIN_PRIMAL, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_PrimordialSeaActivates);
effect++;
}
break;
case ABILITY_DELTA_STREAM:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_STRONG_WINDS, TRUE))
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_STRONG_WINDS, gLastUsedAbility))
{
BattleScriptPushCursorAndCallback(BattleScript_DeltaStreamActivates);
effect++;
@ -4074,13 +4079,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
effect++;
}
break;
case ABILITY_ORICHALCUM_PULSE:
if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SUN, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
effect++;
}
break;
case ABILITY_SUPREME_OVERLORD:
if (!gSpecialStatuses[battler].switchInAbilityDone)
{
@ -4851,7 +4849,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
BattleScriptCall(BattleScript_BlockedByPrimalWeatherRet);
effect++;
}
else if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, TRUE))
else if (TryChangeBattleWeather(battler, BATTLE_WEATHER_SANDSTORM, gLastUsedAbility))
{
gBattleScripting.battler = battler;
BattleScriptCall(BattleScript_SandSpitActivates);
@ -4909,7 +4907,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (!gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN))
{
BattleScriptCall(BattleScript_SeedSowerActivates);
effect++;

View File

@ -200,3 +200,21 @@ SINGLE_BATTLE_TEST("Protosynthesis doesn't activate if Cloud Nine/Air Lock is on
NOT ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
}
}
SINGLE_BATTLE_TEST("Protosynthesis activates after weather was reset")
{
GIVEN {
PLAYER(SPECIES_WALKING_WAKE) { Ability(ABILITY_PROTOSYNTHESIS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SUNNY_DAY); }
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { MOVE(player, MOVE_SUNNY_DAY); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
ANIMATION(ANIM_TYPE_MOVE, MOVE_RAIN_DANCE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
}
}