Fix Powder (status) config and some terrain timers not using gBattleTurnCounter (#6109)
This commit is contained in:
parent
e1e3bcfa91
commit
4158f9251f
@ -70,11 +70,11 @@ If your new Trainer Slide needs to check for beforen initalized, a function is d
|
||||
|
||||
```diff
|
||||
void SetTrainerSlideMessage(enum DifficultyLevel, u32, u32);
|
||||
void TryInitalizeFirstSTABMoveTrainerSlide(u32, u32, u32);
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(u32);
|
||||
+ void TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(u32);
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32);
|
||||
void TryInitalizeTrainerSlideEnemyMonUnaffected(u32);
|
||||
void TryInitializeFirstSTABMoveTrainerSlide(u32, u32, u32);
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(u32);
|
||||
+ void TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(u32);
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32);
|
||||
void TryInitializeTrainerSlideEnemyMonUnaffected(u32);
|
||||
bool32 IsTrainerSlideInitialized(enum TrainerSlideType);
|
||||
```
|
||||
### `src/trainer_slide.c`
|
||||
@ -111,7 +111,7 @@ The function that determines if a Slide should play has different function for m
|
||||
InitalizeTrainerSlide(slideId);
|
||||
}
|
||||
|
||||
+void TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(u32 target)
|
||||
+void TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(u32 target)
|
||||
+{
|
||||
+ enum TrainerSlideType slideId = TRAINER_SLIDE_ENEMY_LANDS_FIRST_CRITICAL_HIT;
|
||||
+
|
||||
@ -150,13 +150,13 @@ In `BattleTurnPassed`, most Trainer Slides are checked to see if they should run
|
||||
{
|
||||
PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker);
|
||||
|
||||
+ TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(gBattlerTarget);
|
||||
TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(gBattlerTarget);
|
||||
+ TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(gBattlerTarget);
|
||||
TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(gBattlerTarget);
|
||||
|
||||
gBattleCommunication[MSG_DISPLAY] = 1;
|
||||
```
|
||||
|
||||
The actual usage of `TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit` is added and is checked whenever a critical hit is scored.
|
||||
The actual usage of `TryInitializeTrainerSlideEnemyLandsFirstCriticalHit` is added and is checked whenever a critical hit is scored.
|
||||
|
||||
### `test/battle/trainer_slides.c`
|
||||
```diff
|
||||
|
||||
@ -128,7 +128,7 @@ struct DisableStruct
|
||||
u16 overwrittenAbility; // abilities overwritten during battle (keep separate from battle history in case of switching)
|
||||
u8 boosterEnergyActivates:1;
|
||||
u8 roostActive:1;
|
||||
u8 unbrudenActive:1;
|
||||
u8 unburdenActive:1;
|
||||
u8 startEmergencyExit:1;
|
||||
u8 neutralizingGas:1;
|
||||
u8 iceFaceActivationPrevention:1; // fixes hit escape move edge case
|
||||
|
||||
@ -12,11 +12,11 @@ struct MessageStatus
|
||||
|
||||
void SetTrainerSlideMessage(enum DifficultyLevel difficulty, u32 trainerId, u32 slideId);
|
||||
enum TrainerSlideTargets ShouldDoTrainerSlide(u32 battler, enum TrainerSlideType slideId);
|
||||
void TryInitalizeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, u32 moveType);
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(u32 target);
|
||||
void TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(u32 target);
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target);
|
||||
void TryInitalizeTrainerSlideEnemyMonUnaffected(u32 target);
|
||||
void TryInitializeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, u32 moveType);
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(u32 target);
|
||||
void TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(u32 target);
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target);
|
||||
void TryInitializeTrainerSlideEnemyMonUnaffected(u32 target);
|
||||
bool32 IsTrainerSlideInitialized(enum TrainerSlideType slideId);
|
||||
bool32 IsTrainerSlidePlayed(enum TrainerSlideType slideId);
|
||||
void InitalizeTrainerSlide(enum TrainerSlideType slideId);
|
||||
|
||||
@ -3777,6 +3777,7 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
#endif // TESTING
|
||||
|
||||
gBattleStruct->speedTieBreaks = RandomUniform(RNG_SPEED_TIE, 0, Factorial(MAX_BATTLERS_COUNT) - 1);
|
||||
gBattleTurnCounter = 0;
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
gBattlerByTurnOrder[i] = i;
|
||||
@ -3901,7 +3902,6 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
gBattleScripting.moveendState = 0;
|
||||
gBattleStruct->faintedActionsState = 0;
|
||||
gBattleStruct->turnCountersTracker = 0;
|
||||
gBattleTurnCounter = 0;
|
||||
|
||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
||||
SetShellSideArmCategory();
|
||||
@ -4778,7 +4778,7 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
|
||||
// various effects
|
||||
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND)
|
||||
speed *= 2;
|
||||
if (gDisableStructs[battler].unbrudenActive)
|
||||
if (gDisableStructs[battler].unburdenActive)
|
||||
speed *= 2;
|
||||
|
||||
// paralysis drop
|
||||
|
||||
@ -2698,8 +2698,8 @@ static void Cmd_critmessage(void)
|
||||
{
|
||||
PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker);
|
||||
|
||||
TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(gBattlerTarget);
|
||||
TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(gBattlerTarget);
|
||||
TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(gBattlerTarget);
|
||||
TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(gBattlerTarget);
|
||||
|
||||
gBattleCommunication[MSG_DISPLAY] = 1;
|
||||
}
|
||||
@ -2846,7 +2846,7 @@ static void Cmd_resultmessage(void)
|
||||
stringId = STRINGID_SUPEREFFECTIVE;
|
||||
}
|
||||
if (stringId == STRINGID_SUPEREFFECTIVE || stringId == STRINGID_SUPEREFFECTIVETWOFOES)
|
||||
TryInitalizeTrainerSlidePlayerLandsFirstSuperEffectiveHit(gBattlerTarget);
|
||||
TryInitializeTrainerSlidePlayerLandsFirstSuperEffectiveHit(gBattlerTarget);
|
||||
break;
|
||||
case MOVE_RESULT_NOT_VERY_EFFECTIVE:
|
||||
if (IsDoubleSpreadMove())
|
||||
@ -3051,7 +3051,7 @@ static void CheckSetUnburden(u8 battler)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_UNBURDEN)
|
||||
{
|
||||
gDisableStructs[battler].unbrudenActive = TRUE;
|
||||
gDisableStructs[battler].unburdenActive = TRUE;
|
||||
RecordAbilityBattle(battler, ABILITY_UNBURDEN);
|
||||
}
|
||||
}
|
||||
@ -3074,7 +3074,7 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
|
||||
gBattleMons[battlerStealer].item = gLastUsedItem;
|
||||
|
||||
gDisableStructs[battlerStealer].unbrudenActive = FALSE;
|
||||
gDisableStructs[battlerStealer].unburdenActive = FALSE;
|
||||
BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
|
||||
MarkBattlerForControllerExec(battlerStealer);
|
||||
}
|
||||
@ -8606,7 +8606,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef)
|
||||
gBattleMons[battlerDef].item = gLastUsedItem;
|
||||
BtlController_EmitSetMonData(battlerDef, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battlerDef].item), &gBattleMons[battlerDef].item);
|
||||
MarkBattlerForControllerExec(battlerDef);
|
||||
gDisableStructs[battlerDef].unbrudenActive = FALSE;
|
||||
gDisableStructs[battlerDef].unburdenActive = FALSE;
|
||||
}
|
||||
|
||||
// Called by Cmd_removeitem. itemId represents the item that was removed, not being given.
|
||||
@ -14658,8 +14658,8 @@ static void Cmd_tryswapitems(void)
|
||||
}
|
||||
else if (oldItemAtk == ITEM_NONE && *newItemAtk != ITEM_NONE)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNBURDEN && gDisableStructs[gBattlerAttacker].unbrudenActive)
|
||||
gDisableStructs[gBattlerAttacker].unbrudenActive = FALSE;
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNBURDEN && gDisableStructs[gBattlerAttacker].unburdenActive)
|
||||
gDisableStructs[gBattlerAttacker].unburdenActive = FALSE;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ITEM_SWAP_TAKEN; // nothing -> <- target's item
|
||||
}
|
||||
@ -16958,7 +16958,7 @@ void BS_SetRemoveTerrain(void)
|
||||
|
||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
|
||||
gFieldStatuses |= statusFlag;
|
||||
gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5;
|
||||
gFieldTimers.terrainTimer = gBattleTurnCounter + (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,7 +1134,7 @@ void PrepareStringBattle(u16 stringId, u32 battler)
|
||||
}
|
||||
|
||||
if ((stringId == STRINGID_ITDOESNTAFFECT || stringId == STRINGID_PKMNWASNTAFFECTED || stringId == STRINGID_PKMNUNAFFECTED))
|
||||
TryInitalizeTrainerSlideEnemyMonUnaffected(gBattlerTarget);
|
||||
TryInitializeTrainerSlideEnemyMonUnaffected(gBattlerTarget);
|
||||
|
||||
BtlController_EmitPrintString(battler, BUFFER_A, stringId);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
@ -3135,6 +3135,18 @@ static inline bool32 TryFormChangeBeforeMove(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline bool32 TryActivatePowderStatus(u32 move)
|
||||
{
|
||||
u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]];
|
||||
if (GetBattleMoveType(move) == TYPE_FIRE && !gBattleStruct->pledgeMove)
|
||||
return TRUE;
|
||||
if (move == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE)
|
||||
return TRUE;
|
||||
if (move == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetAtkCancellerForCalledMove(void)
|
||||
{
|
||||
gBattleStruct->atkCancellerTracker = CANCELLER_HEAL_BLOCKED;
|
||||
@ -3550,7 +3562,7 @@ static void CancellerWeatherPrimal(u32 *effect)
|
||||
if (HasWeatherEffect() && GetMovePower(gCurrentMove) > 0)
|
||||
{
|
||||
u32 moveType = GetBattleMoveType(gCurrentMove);
|
||||
if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
|
||||
if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL) && (B_POWDER_RAIN >= GEN_7 || !TryActivatePowderStatus(gCurrentMove)))
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
|
||||
*effect = 1;
|
||||
@ -3606,14 +3618,10 @@ static void CancellerPowderStatus(u32 *effect)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER)
|
||||
{
|
||||
u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]];
|
||||
if ((GetBattleMoveType(gCurrentMove) == TYPE_FIRE && !gBattleStruct->pledgeMove)
|
||||
|| (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE)
|
||||
|| (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove))
|
||||
if (TryActivatePowderStatus(gCurrentMove))
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE;
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
|
||||
&& (B_POWDER_RAIN < GEN_7 || !IsBattlerWeatherAffected(gBattlerAttacker, B_WEATHER_RAIN_PRIMAL)))
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
|
||||
|
||||
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE
|
||||
@ -4058,9 +4066,9 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u16 *timer)
|
||||
gDisableStructs[battler].terrainAbilityDone = FALSE;
|
||||
|
||||
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
|
||||
*timer = 8;
|
||||
*timer = gBattleTurnCounter + 8;
|
||||
else
|
||||
*timer = 5;
|
||||
*timer = gBattleTurnCounter + 5;
|
||||
|
||||
gBattleScripting.battler = battler;
|
||||
return TRUE;
|
||||
@ -10736,7 +10744,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov
|
||||
}
|
||||
|
||||
if (recordAbilities)
|
||||
TryInitalizeFirstSTABMoveTrainerSlide(battlerDef, battlerAtk, moveType);
|
||||
TryInitializeFirstSTABMoveTrainerSlide(battlerDef, battlerAtk, moveType);
|
||||
|
||||
return modifier;
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ static bool32 IsSlideInitalizedOrPlayed(enum TrainerSlideType slideId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TryInitalizeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, u32 moveType)
|
||||
void TryInitializeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, u32 moveType)
|
||||
{
|
||||
enum TrainerSlideType slideId = TRAINER_SLIDE_PLAYER_LANDS_FIRST_STAB_MOVE;
|
||||
|
||||
@ -316,7 +316,7 @@ void TryInitalizeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, u32 m
|
||||
InitalizeTrainerSlide(slideId);
|
||||
}
|
||||
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(u32 target)
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(u32 target)
|
||||
{
|
||||
enum TrainerSlideType slideId = TRAINER_SLIDE_PLAYER_LANDS_FIRST_CRITICAL_HIT;
|
||||
|
||||
@ -329,7 +329,7 @@ void TryInitalizeTrainerSlidePlayerLandsFirstCriticalHit(u32 target)
|
||||
InitalizeTrainerSlide(slideId);
|
||||
}
|
||||
|
||||
void TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(u32 target)
|
||||
void TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(u32 target)
|
||||
{
|
||||
enum TrainerSlideType slideId = TRAINER_SLIDE_ENEMY_LANDS_FIRST_CRITICAL_HIT;
|
||||
|
||||
@ -342,7 +342,7 @@ void TryInitalizeTrainerSlideEnemyLandsFirstCriticalHit(u32 target)
|
||||
InitalizeTrainerSlide(slideId);
|
||||
}
|
||||
|
||||
void TryInitalizeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target)
|
||||
void TryInitializeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target)
|
||||
{
|
||||
enum TrainerSlideType slideId = TRAINER_SLIDE_PLAYER_LANDS_FIRST_SUPER_EFFECTIVE_HIT;
|
||||
|
||||
@ -355,7 +355,7 @@ void TryInitalizeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target)
|
||||
InitalizeTrainerSlide(slideId);
|
||||
}
|
||||
|
||||
void TryInitalizeTrainerSlideEnemyMonUnaffected(u32 target)
|
||||
void TryInitializeTrainerSlideEnemyMonUnaffected(u32 target)
|
||||
{
|
||||
enum TrainerSlideType slideId = TRAINER_SLIDE_ENEMY_MON_UNAFFECTED;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user