Introduces BattleTurnCounter to simplfy timer checks (#6080)

This commit is contained in:
Alex 2025-01-25 20:26:38 +01:00 committed by GitHub
parent 88986baf5f
commit 77b677dbf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 123 additions and 136 deletions

View File

@ -238,49 +238,49 @@ struct SpecialStatus
struct SideTimer
{
u8 reflectTimer;
u16 reflectTimer;
u8 reflectBattlerId;
u8 lightscreenTimer;
u16 lightscreenTimer;
u8 lightscreenBattlerId;
u8 mistTimer;
u16 mistTimer;
u8 mistBattlerId;
u8 safeguardTimer;
u16 safeguardTimer;
u8 safeguardBattlerId;
u8 spikesAmount;
u8 toxicSpikesAmount;
u8 stealthRockAmount;
u8 stickyWebAmount;
u16 spikesAmount; // debug menu complains. might be better to solve there instead if possible
u16 toxicSpikesAmount;
u16 stealthRockAmount;
u16 stickyWebAmount;
u8 stickyWebBattlerId;
u8 stickyWebBattlerSide; // Used for Court Change
u8 auroraVeilTimer;
u16 auroraVeilTimer;
u8 auroraVeilBattlerId;
u8 tailwindTimer;
u16 tailwindTimer;
u8 tailwindBattlerId;
u8 luckyChantTimer;
u16 luckyChantTimer;
u8 luckyChantBattlerId;
u8 steelsurgeAmount;
u16 steelsurgeAmount;
// Timers below this point are not swapped by Court Change
u8 followmeTimer;
u16 followmeTimer;
u8 followmeTarget:3;
u8 followmePowder:1; // Rage powder, does not affect grass type pokemon.
u8 retaliateTimer;
u8 damageNonTypesTimer;
u16 retaliateTimer;
u16 damageNonTypesTimer;
u8 damageNonTypesType;
u8 rainbowTimer;
u8 seaOfFireTimer;
u8 swampTimer;
u16 rainbowTimer;
u16 seaOfFireTimer;
u16 swampTimer;
};
struct FieldTimer
{
u8 mudSportTimer;
u8 waterSportTimer;
u8 wonderRoomTimer;
u8 magicRoomTimer;
u8 trickRoomTimer;
u8 terrainTimer;
u8 gravityTimer;
u8 fairyLockTimer;
u16 mudSportTimer;
u16 waterSportTimer;
u16 wonderRoomTimer;
u16 magicRoomTimer;
u16 trickRoomTimer;
u16 terrainTimer;
u16 gravityTimer;
u16 fairyLockTimer;
};
struct WishFutureKnock
@ -289,7 +289,7 @@ struct WishFutureKnock
u8 futureSightBattlerIndex[MAX_BATTLERS_COUNT];
u8 futureSightPartyIndex[MAX_BATTLERS_COUNT];
u16 futureSightMove[MAX_BATTLERS_COUNT];
u8 wishCounter[MAX_BATTLERS_COUNT];
u16 wishCounter[MAX_BATTLERS_COUNT];
u8 wishPartyId[MAX_BATTLERS_COUNT];
u8 weatherDuration;
u8 knockedOffMons[NUM_BATTLE_SIDES]; // Each battler is represented by a bit.
@ -1169,6 +1169,7 @@ extern u16 gBattleMovePower;
extern u16 gMoveToLearn;
extern u32 gFieldStatuses;
extern struct FieldTimer gFieldTimers;
extern u16 gBattleTurnCounter;
extern u8 gBattlerAbility;
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];

View File

@ -2102,8 +2102,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
break;
case EFFECT_DEFOG:
if (gSideStatuses[GetBattlerSide(battlerDef)]
& (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST)
|| gSideTimers[GetBattlerSide(battlerDef)].auroraVeilTimer != 0
& (SIDE_STATUS_SCREEN_ANY | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST)
|| gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY)
{
if (PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
@ -2201,7 +2200,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-4);
break;
case EFFECT_WISH:
if (gWishFutureKnock.wishCounter[battlerAtk] != 0)
if (gWishFutureKnock.wishCounter[battlerAtk] > gBattleTurnCounter)
ADJUST_SCORE(-10);
break;
case EFFECT_ASSIST:
@ -2614,13 +2613,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
break;
case EFFECT_TAILWIND:
if (gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer != 0
|| PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TAILWIND)
|| (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1)) // Trick Room active and not ending this turn
if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_TAILWIND
|| PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TAILWIND)
|| gFieldStatuses & STATUS_FIELD_TRICK_ROOM)
ADJUST_SCORE(-10);
break;
case EFFECT_LUCKY_CHANT:
if (gSideTimers[GetBattlerSide(battlerAtk)].luckyChantTimer != 0
if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_LUCKY_CHANT
|| PartnerMoveIsSameNoTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10);
break;
@ -5320,7 +5319,7 @@ static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
switch (moveEffect)
{
case EFFECT_TAILWIND:
if (!gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1))
if (!gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM))
ADJUST_SCORE(POWERFUL_STATUS_MOVE);
break;
case EFFECT_TRICK_ROOM:

View File

@ -2174,7 +2174,7 @@ static bool32 ShouldUseItem(u32 battler)
break;
case EFFECT_ITEM_SET_MIST:
battlerSide = GetBattlerSide(battler);
if (gDisableStructs[battler].isFirstTurn && gSideTimers[battlerSide].mistTimer == 0)
if (gDisableStructs[battler].isFirstTurn && !(gSideStatuses[battlerSide] & SIDE_STATUS_MIST))
shouldUse = TRUE;
break;
case EFFECT_ITEM_REVIVE:

View File

@ -6693,16 +6693,21 @@ static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
// if used future sight on opposing side, properly track who used it
if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) {
for (i = 0; i < gBattlersCount; i++) {
if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK)
{
for (i = 0; i < gBattlersCount; i++)
{
if (IsAlly(i,battlerAtk))
continue; // only on opposing side
if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) {
if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk)
{
// if target was attacked with future sight from us, now they'll be the partner slot
gWishFutureKnock.futureSightBattlerIndex[i] = battlerPartner;
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerPartner];
break;
} else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) {
}
else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner)
{
gWishFutureKnock.futureSightBattlerIndex[i] = battlerAtk;
gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerAtk];
break;
@ -6711,10 +6716,9 @@ static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
}
// swap wish party indices
if (gWishFutureKnock.wishCounter[battlerAtk] > 0
|| gWishFutureKnock.wishCounter[battlerPartner] > 0) {
if (gWishFutureKnock.wishCounter[battlerAtk] > gBattleTurnCounter
|| gWishFutureKnock.wishCounter[battlerPartner] > gBattleTurnCounter)
SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp);
}
}
static void AnimTask_AllySwitchDataSwap(u8 taskId)

View File

@ -818,7 +818,7 @@ static void PrintDigitChars(struct BattleDebugMenu *data);
static void SetUpModifyArrows(struct BattleDebugMenu *data);
static void UpdateBattlerValue(struct BattleDebugMenu *data);
static void UpdateMonData(struct BattleDebugMenu *data);
static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue);
static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue);
static bool32 TryMoveDigit(struct BattleDebugModifyArrows *modArrows, bool32 moveUp);
static void SwitchToDebugView(u8 taskId);
static void SwitchToDebugViewFromAiParty(u8 taskId);
@ -1852,7 +1852,7 @@ static void ValueToCharDigits(u8 *charDigits, u32 newValue, u8 maxDigits)
charDigits[i] = valueDigits[i] + CHAR_0;
}
static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue)
static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue)
{
struct SideTimer *sideTimer = &gSideTimers[GetBattlerSide(data->battlerId)];

View File

@ -646,9 +646,9 @@ void BS_SetMaxMoveEffect(void)
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
gFieldTimers.terrainTimer = 8;
gFieldTimers.terrainTimer = gBattleTurnCounter + 8;
else
gFieldTimers.terrainTimer = 5;
gFieldTimers.terrainTimer = gBattleTurnCounter + 5;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectSetTerrain;
effect++;
@ -665,7 +665,7 @@ void BS_SetMaxMoveEffect(void)
{
u32 moveType = GetMoveType(gCurrentMove);
gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES;
gSideTimers[side].damageNonTypesTimer = 5; // damage is dealt for 4 turns, ends on 5th
gSideTimers[side].damageNonTypesTimer = gBattleTurnCounter + 5; // damage is dealt for 4 turns, ends on 5th
gSideTimers[side].damageNonTypesType = moveType;
BattleScriptPush(gBattlescriptCurrInstr + 1);
ChooseDamageNonTypesString(moveType);
@ -708,9 +708,9 @@ void BS_SetMaxMoveEffect(void)
{
gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_AURORA_VEIL;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = 8;
gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 8;
else
gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilBattlerId = gBattlerAttacker;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD;
BattleScriptPush(gBattlescriptCurrInstr + 1);
@ -722,7 +722,7 @@ void BS_SetMaxMoveEffect(void)
if (!(gFieldStatuses & STATUS_FIELD_GRAVITY))
{
gFieldStatuses |= STATUS_FIELD_GRAVITY;
gFieldTimers.gravityTimer = 5;
gFieldTimers.gravityTimer = gBattleTurnCounter + 5;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectGravitySuccess;
effect++;

View File

@ -225,6 +225,7 @@ EWRAM_DATA u16 gBattleMovePower = 0;
EWRAM_DATA u16 gMoveToLearn = 0;
EWRAM_DATA u32 gFieldStatuses = 0;
EWRAM_DATA struct FieldTimer gFieldTimers = {0};
EWRAM_DATA u16 gBattleTurnCounter = 0;
EWRAM_DATA u8 gBattlerAbility = 0;
EWRAM_DATA struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
@ -3900,6 +3901,7 @@ static void TryDoEventsBeforeFirstTurn(void)
gBattleScripting.moveendState = 0;
gBattleStruct->faintedActionsState = 0;
gBattleStruct->turnCountersTracker = 0;
gBattleTurnCounter = 0;
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
SetShellSideArmCategory();
@ -3954,9 +3956,10 @@ void BattleTurnPassed(void)
return;
if (DoBattlerEndTurnEffects())
return;
if (HandleWishPerishSongOnTurnEnd())
return;
}
if (HandleWishPerishSongOnTurnEnd())
return;
if (HandleFaintedMonActions())
return;
gBattleStruct->faintedActionsState = 0;

View File

@ -4225,9 +4225,9 @@ void SetMoveEffect(bool32 primary, bool32 certain)
{
gSideStatuses[side] |= SIDE_STATUS_REFLECT;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[side].reflectTimer = 8;
gSideTimers[side].reflectTimer = gBattleTurnCounter + 8;
else
gSideTimers[side].reflectTimer = 5;
gSideTimers[side].reflectTimer = gBattleTurnCounter + 5;
gSideTimers[side].reflectBattlerId = gBattlerAttacker;
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
@ -4245,9 +4245,9 @@ void SetMoveEffect(bool32 primary, bool32 certain)
{
gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[side].lightscreenTimer = 8;
gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 8;
else
gSideTimers[side].lightscreenTimer = 5;
gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 5;
gSideTimers[side].lightscreenBattlerId = gBattlerAttacker;
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
@ -8568,7 +8568,7 @@ static void Cmd_setgravity(void)
else
{
gFieldStatuses |= STATUS_FIELD_GRAVITY;
gFieldTimers.gravityTimer = 5;
gFieldTimers.gravityTimer = gBattleTurnCounter + 5;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@ -9145,7 +9145,6 @@ static void RemoveAllWeather(void)
static void RemoveAllTerrains(void)
{
gFieldTimers.terrainTimer = 0;
switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)
{
case STATUS_FIELD_MISTY_TERRAIN:
@ -9637,7 +9636,7 @@ static void Cmd_various(void)
else
{
gFieldStatuses |= STATUS_FIELD_FAIRY_LOCK;
gFieldTimers.fairyLockTimer = 2;
gFieldTimers.fairyLockTimer = gBattleTurnCounter + 2;
gBattlescriptCurrInstr = cmd->nextInstr;
}
return;
@ -10270,7 +10269,7 @@ static void Cmd_various(void)
{
gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_LUCKY_CHANT;
gSideTimers[GetBattlerSide(battler)].luckyChantBattlerId = battler;
gSideTimers[GetBattlerSide(battler)].luckyChantTimer = 5;
gSideTimers[GetBattlerSide(battler)].luckyChantTimer = gBattleTurnCounter + 5;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@ -10729,9 +10728,9 @@ static void Cmd_various(void)
{
gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_AURORA_VEIL;
if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 8;
gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 8;
else
gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 5;
gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(battler)].auroraVeilBattlerId = battler;
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
@ -11600,9 +11599,9 @@ static void Cmd_setreflect(void)
{
gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_REFLECT;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 8;
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = gBattleTurnCounter + 8;
else
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker;
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
@ -12647,9 +12646,9 @@ static void Cmd_setlightscreen(void)
{
gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_LIGHTSCREEN;
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 8;
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = gBattleTurnCounter + 8;
else
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker;
if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
@ -12861,7 +12860,7 @@ static void Cmd_setmist(void)
}
else
{
gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].mistBattlerId = gBattlerAttacker;
gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_MIST;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MIST;
@ -13515,7 +13514,7 @@ static void Cmd_settailwind(void)
{
gSideStatuses[side] |= SIDE_STATUS_TAILWIND;
gSideTimers[side].tailwindBattlerId = gBattlerAttacker;
gSideTimers[side].tailwindTimer = B_TAILWIND_TURNS >= GEN_5 ? 4 : 3;
gSideTimers[side].tailwindTimer = gBattleTurnCounter + (B_TAILWIND_TURNS >= GEN_5 ? 4 : 3);
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@ -13929,7 +13928,7 @@ static void Cmd_setsafeguard(void)
else
{
gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_SAFEGUARD;
gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardTimer = 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardTimer = gBattleTurnCounter + 5;
gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardBattlerId = gBattlerAttacker;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD;
}
@ -14225,7 +14224,7 @@ static void Cmd_trysetfutureattack(void)
{
CMD_ARGS(const u8 *failInstr);
if (gWishFutureKnock.futureSightCounter[gBattlerTarget] != 0)
if (gWishFutureKnock.futureSightCounter[gBattlerTarget] > gBattleTurnCounter)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
@ -14235,7 +14234,7 @@ static void Cmd_trysetfutureattack(void)
gWishFutureKnock.futureSightMove[gBattlerTarget] = gCurrentMove;
gWishFutureKnock.futureSightBattlerIndex[gBattlerTarget] = gBattlerAttacker;
gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] = gBattlerPartyIndexes[gBattlerAttacker];
gWishFutureKnock.futureSightCounter[gBattlerTarget] = 3;
gWishFutureKnock.futureSightCounter[gBattlerTarget] = gBattleTurnCounter + 3;
if (gCurrentMove == MOVE_DOOM_DESIRE)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DOOM_DESIRE;
@ -14705,9 +14704,9 @@ static void Cmd_trywish(void)
switch (cmd->turnNumber)
{
case 0: // use wish
if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0)
if (gWishFutureKnock.wishCounter[gBattlerAttacker] <= gBattleTurnCounter)
{
gWishFutureKnock.wishCounter[gBattlerAttacker] = 2;
gWishFutureKnock.wishCounter[gBattlerAttacker] = gBattleTurnCounter + 2;
gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker];
gBattlescriptCurrInstr = cmd->nextInstr;
}
@ -14818,18 +14817,17 @@ static void Cmd_setdamagetohealthdifference(void)
}
}
static void HandleRoomMove(u32 statusFlag, u8 *timer, u8 stringId)
static void HandleRoomMove(u32 statusFlag, u16 *timer, u8 stringId)
{
if (gFieldStatuses & statusFlag)
{
gFieldStatuses &= ~statusFlag;
*timer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = stringId + 1;
}
else
{
gFieldStatuses |= statusFlag;
*timer = 5;
*timer = gBattleTurnCounter + 5;
gBattleCommunication[MULTISTRING_CHOOSER] = stringId;
}
}
@ -15227,7 +15225,7 @@ static void Cmd_settypebasedhalvers(void)
if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT))
{
gFieldStatuses |= STATUS_FIELD_MUDSPORT;
gFieldTimers.mudSportTimer = 5;
gFieldTimers.mudSportTimer = gBattleTurnCounter + 5;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC;
worked = TRUE;
}
@ -15249,7 +15247,7 @@ static void Cmd_settypebasedhalvers(void)
if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT))
{
gFieldStatuses |= STATUS_FIELD_WATERSPORT;
gFieldTimers.waterSportTimer = 5;
gFieldTimers.waterSportTimer = gBattleTurnCounter + 5;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE;
worked = TRUE;
}
@ -15434,17 +15432,9 @@ static void Cmd_removelightscreenreflect(void)
else
failed = FALSE;
if (!failed
&& (gSideTimers[side].reflectTimer
|| gSideTimers[side].lightscreenTimer
|| gSideTimers[side].auroraVeilTimer))
if (!failed && gSideStatuses[side] & SIDE_STATUS_SCREEN_ANY)
{
gSideStatuses[side] &= ~SIDE_STATUS_REFLECT;
gSideStatuses[side] &= ~SIDE_STATUS_LIGHTSCREEN;
gSideStatuses[side] &= ~SIDE_STATUS_AURORA_VEIL;
gSideTimers[side].reflectTimer = 0;
gSideTimers[side].lightscreenTimer = 0;
gSideTimers[side].auroraVeilTimer = 0;
gSideStatuses[side] &= ~SIDE_STATUS_SCREEN_ANY;
gBattleScripting.animTurn = 1;
gBattleScripting.animTargetsHit = 1;
}
@ -17178,13 +17168,13 @@ void BS_SetPledgeStatus(void)
switch (cmd->sideStatus)
{
case SIDE_STATUS_RAINBOW:
gSideTimers[side].rainbowTimer = 4;
gSideTimers[side].rainbowTimer = gBattleTurnCounter + 4;
break;
case SIDE_STATUS_SEA_OF_FIRE:
gSideTimers[side].seaOfFireTimer = 4;
gSideTimers[side].seaOfFireTimer = gBattleTurnCounter + 4;
break;
case SIDE_STATUS_SWAMP:
gSideTimers[side].swampTimer = 4;
gSideTimers[side].swampTimer = gBattleTurnCounter + 4;
}
gBattlescriptCurrInstr = cmd->nextInstr;

View File

@ -1655,7 +1655,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId)
{
if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN)
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
if (gFieldTimers.terrainTimer > 0 && --gFieldTimers.terrainTimer == 0)
if (gFieldTimers.terrainTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~terrainFlag;
TryToRevertMimicryAndFlags();
@ -1737,7 +1737,7 @@ u8 DoFieldEndTurnEffects(void)
SwapTurnOrder(i, j);
}
}
gBattleTurnCounter++;
gBattleStruct->turnCountersTracker++;
gBattleStruct->turnSideTracker = 0;
// fall through
@ -1748,7 +1748,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].reflectBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_REFLECT)
{
if (--gSideTimers[side].reflectTimer == 0)
if (gSideTimers[side].reflectTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_REFLECT;
BattleScriptExecute(BattleScript_SideStatusWoreOff);
@ -1773,7 +1773,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].lightscreenBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN)
{
if (--gSideTimers[side].lightscreenTimer == 0)
if (gSideTimers[side].lightscreenTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_LIGHTSCREEN;
BattleScriptExecute(BattleScript_SideStatusWoreOff);
@ -1799,7 +1799,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].auroraVeilBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_AURORA_VEIL)
{
if (--gSideTimers[side].auroraVeilTimer == 0)
if (gSideTimers[side].auroraVeilTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_AURORA_VEIL;
BattleScriptExecute(BattleScript_SideStatusWoreOff);
@ -1823,7 +1823,7 @@ u8 DoFieldEndTurnEffects(void)
{
side = gBattleStruct->turnSideTracker;
gBattlerAttacker = gSideTimers[side].mistBattlerId;
if (gSideTimers[side].mistTimer != 0 && --gSideTimers[side].mistTimer == 0)
if (gSideTimers[side].mistTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_MIST;
BattleScriptExecute(BattleScript_SideStatusWoreOff);
@ -1848,7 +1848,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].safeguardBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_SAFEGUARD)
{
if (--gSideTimers[side].safeguardTimer == 0)
if (gSideTimers[side].safeguardTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_SAFEGUARD;
BattleScriptExecute(BattleScript_SafeguardEnds);
@ -1872,7 +1872,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].luckyChantBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_LUCKY_CHANT)
{
if (--gSideTimers[side].luckyChantTimer == 0)
if (gSideTimers[side].luckyChantTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_LUCKY_CHANT;
BattleScriptExecute(BattleScript_LuckyChantEnds);
@ -1896,7 +1896,7 @@ u8 DoFieldEndTurnEffects(void)
gBattlerAttacker = gSideTimers[side].tailwindBattlerId;
if (gSideStatuses[side] & SIDE_STATUS_TAILWIND)
{
if (gSideTimers[side].tailwindTimer > 0 && --gSideTimers[side].tailwindTimer == 0)
if (gSideTimers[side].tailwindTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_TAILWIND;
BattleScriptExecute(BattleScript_TailwindEnds);
@ -1917,9 +1917,7 @@ u8 DoFieldEndTurnEffects(void)
while (gBattleStruct->turnSideTracker < gBattlersCount)
{
u32 battler = gBattlerByTurnOrder[gBattleStruct->turnSideTracker];
if (gWishFutureKnock.wishCounter[battler] != 0
&& --gWishFutureKnock.wishCounter[battler] == 0
&& IsBattlerAlive(battler))
if (gWishFutureKnock.wishCounter[battler] == gBattleTurnCounter && IsBattlerAlive(battler))
{
gBattlerTarget = battler;
BattleScriptExecute(BattleScript_WishComesTrue);
@ -1943,7 +1941,7 @@ u8 DoFieldEndTurnEffects(void)
while (gBattleStruct->turnSideTracker < 2)
{
side = gBattleStruct->turnSideTracker;
if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES && --gSideTimers[side].damageNonTypesTimer == 0)
if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES && gSideTimers[side].damageNonTypesTimer == gBattleTurnCounter)
{
// There is no in-game message when this side status ends.
gSideStatuses[side] &= ~SIDE_STATUS_DAMAGE_NON_TYPES;
@ -1960,7 +1958,7 @@ u8 DoFieldEndTurnEffects(void)
}
break;
case ENDTURN_TRICK_ROOM:
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 0 && --gFieldTimers.trickRoomTimer == 0)
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_TRICK_ROOM;
BattleScriptExecute(BattleScript_TrickRoomEnds);
@ -1969,7 +1967,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_WONDER_ROOM:
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM && gFieldTimers.wonderRoomTimer > 0 && --gFieldTimers.wonderRoomTimer == 0)
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM && gFieldTimers.wonderRoomTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_WONDER_ROOM;
BattleScriptExecute(BattleScript_WonderRoomEnds);
@ -1978,7 +1976,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_MAGIC_ROOM:
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM && gFieldTimers.magicRoomTimer > 0 && --gFieldTimers.magicRoomTimer == 0)
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM && gFieldTimers.magicRoomTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_MAGIC_ROOM;
BattleScriptExecute(BattleScript_MagicRoomEnds);
@ -2003,7 +2001,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_WATER_SPORT:
if (gFieldStatuses & STATUS_FIELD_WATERSPORT && --gFieldTimers.waterSportTimer == 0)
if (gFieldStatuses & STATUS_FIELD_WATERSPORT && gFieldTimers.waterSportTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_WATERSPORT;
BattleScriptExecute(BattleScript_WaterSportEnds);
@ -2012,7 +2010,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_MUD_SPORT:
if (gFieldStatuses & STATUS_FIELD_MUDSPORT && --gFieldTimers.mudSportTimer == 0)
if (gFieldStatuses & STATUS_FIELD_MUDSPORT && gFieldTimers.mudSportTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_MUDSPORT;
BattleScriptExecute(BattleScript_MudSportEnds);
@ -2021,7 +2019,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_GRAVITY:
if (gFieldStatuses & STATUS_FIELD_GRAVITY && --gFieldTimers.gravityTimer == 0)
if (gFieldStatuses & STATUS_FIELD_GRAVITY && gFieldTimers.gravityTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_GRAVITY;
BattleScriptExecute(BattleScript_GravityEnds);
@ -2034,7 +2032,7 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_FAIRY_LOCK:
if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK && --gFieldTimers.fairyLockTimer == 0)
if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK && gFieldTimers.fairyLockTimer == gBattleTurnCounter)
{
gFieldStatuses &= ~STATUS_FIELD_FAIRY_LOCK;
}
@ -2067,7 +2065,7 @@ u8 DoFieldEndTurnEffects(void)
break;
}
if (gSideTimers[side].rainbowTimer > 0 && --gSideTimers[side].rainbowTimer == 0)
if (gSideTimers[side].rainbowTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_RAINBOW;
BattleScriptExecute(BattleScript_TheRainbowDisappeared);
@ -2097,7 +2095,7 @@ u8 DoFieldEndTurnEffects(void)
break;
}
if (gSideTimers[side].seaOfFireTimer > 0 && --gSideTimers[side].seaOfFireTimer == 0)
if (gSideTimers[side].seaOfFireTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_SEA_OF_FIRE;
BattleScriptExecute(BattleScript_TheSeaOfFireDisappeared);
@ -2127,7 +2125,7 @@ u8 DoFieldEndTurnEffects(void)
break;
}
if (gSideTimers[side].swampTimer > 0 && --gSideTimers[side].swampTimer == 0)
if (gSideTimers[side].swampTimer == gBattleTurnCounter)
{
gSideStatuses[side] &= ~SIDE_STATUS_SWAMP;
BattleScriptExecute(BattleScript_TheSwampDisappeared);
@ -2873,7 +2871,7 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_GMAX_MOVE_RESIDUAL_DAMAGE:
{
u32 side = GetBattlerSide(gBattlerAttacker);
if (gSideTimers[side].damageNonTypesTimer
if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES
&& !IS_BATTLER_OF_TYPE(gBattlerAttacker, gSideTimers[side].damageNonTypesType)
&& IsBattlerAlive(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
@ -2926,14 +2924,12 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
gBattleStruct->wishPerishSongBattlerId++;
if (gWishFutureKnock.futureSightCounter[battler] != 0
&& --gWishFutureKnock.futureSightCounter[battler] == 0
&& !(gAbsentBattlerFlags & (1u << battler)))
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler)))
{
struct Pokemon *party;
if (gWishFutureKnock.futureSightCounter[battler] == 0
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0)
if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter
&& gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter)
{
gSideStatuses[GetBattlerSide(battler)] &= ~SIDE_STATUS_FUTUREATTACK;
}
@ -4053,7 +4049,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbilit
return FALSE;
}
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u16 *timer)
{
if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
{
@ -4339,7 +4335,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov
return effect;
}
static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *timer)
static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u16 *timer)
{
if (!(gFieldStatuses & flag))
{
@ -4347,7 +4343,7 @@ static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *ti
gFieldStatuses |= flag;
gBattleScripting.animArg1 = anim;
if (gBattleStruct->startingStatusTimer)
*timer = gBattleStruct->startingStatusTimer;
*timer = gBattleTurnCounter + gBattleStruct->startingStatusTimer;
else
*timer = 0; // Infinite
@ -4357,7 +4353,7 @@ static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *ti
return 0;
}
static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u8 *timer)
static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u16 *timer)
{
if (!(gSideStatuses[side] & flag))
{
@ -4366,7 +4362,7 @@ static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 ani
gSideStatuses[side] |= flag;
gBattleScripting.animArg1 = anim;
if (gBattleStruct->startingStatusTimer)
*timer = gBattleStruct->startingStatusTimer;
*timer = gBattleTurnCounter + gBattleStruct->startingStatusTimer;
else
*timer = 0; // Infinite
@ -11380,22 +11376,16 @@ static bool32 TryRemoveScreens(u32 battler)
u8 enemySide = GetBattlerSide(BATTLE_OPPOSITE(battler));
// try to remove from battler's side
if (gSideStatuses[battlerSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL))
if (gSideStatuses[battlerSide] & SIDE_STATUS_SCREEN_ANY)
{
gSideStatuses[battlerSide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL);
gSideTimers[battlerSide].reflectTimer = 0;
gSideTimers[battlerSide].lightscreenTimer = 0;
gSideTimers[battlerSide].auroraVeilTimer = 0;
gSideStatuses[battlerSide] &= ~SIDE_STATUS_SCREEN_ANY;
removed = TRUE;
}
// try to remove from battler opponent's side
if (gSideStatuses[enemySide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL))
if (gSideStatuses[enemySide] & SIDE_STATUS_SCREEN_ANY)
{
gSideStatuses[enemySide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL);
gSideTimers[enemySide].reflectTimer = 0;
gSideTimers[enemySide].lightscreenTimer = 0;
gSideTimers[enemySide].auroraVeilTimer = 0;
gSideStatuses[enemySide] &= ~SIDE_STATUS_SCREEN_ANY;
removed = TRUE;
}