mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Optimize GetWhichBattlerFasterOrTies (#7953)
This commit is contained in:
parent
3ad78d0079
commit
a77f8d97a1
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef GUARD_BATTLE_MAIN_H
|
||||
#define GUARD_BATTLE_MAIN_H
|
||||
|
||||
#include "battle_util.h"
|
||||
#include "pokemon.h"
|
||||
#include "data.h"
|
||||
#include "constants/hold_effects.h"
|
||||
|
|
@ -97,14 +98,12 @@ u8 IsRunningFromBattleImpossible(u32 battler);
|
|||
void SwitchTwoBattlersInParty(u32 battler, u32 battler2);
|
||||
void SwitchPartyOrder(u32 battler);
|
||||
void SwapTurnOrder(u8 id1, u8 id2);
|
||||
u32 GetBattlerTotalSpeedStatArgs(u32 battler, enum Ability ability, enum HoldEffect holdEffect);
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler);
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler, enum Ability ability, enum HoldEffect holdEffect);
|
||||
s32 GetChosenMovePriority(u32 battler, enum Ability ability);
|
||||
s32 GetBattleMovePriority(u32 battler, enum Ability ability, u32 move);
|
||||
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, enum Ability ability1, enum Ability ability2,
|
||||
enum HoldEffect holdEffectBattler1, enum HoldEffect holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
|
||||
s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
|
||||
s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
|
||||
s32 GetWhichBattlerFasterArgs(struct BattleContext *ctx, bool32 ignoreChosenMoves, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
|
||||
s32 GetWhichBattlerFasterOrTies(struct BattleContext *ctx, bool32 ignoreChosenMoves);
|
||||
s32 GetWhichBattlerFaster(struct BattleContext *ctx, bool32 ignoreChosenMoves);
|
||||
void RunBattleScriptCommands_PopCallbacksStack(void);
|
||||
void RunBattleScriptCommands(void);
|
||||
u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState monInBattle);
|
||||
|
|
|
|||
|
|
@ -558,7 +558,7 @@ void SetBattlerAiData(u32 battler, struct AiLogicData *aiData)
|
|||
aiData->lastUsedMove[battler] = gLastMoves[battler];
|
||||
aiData->hpPercents[battler] = GetHealthPercentage(battler);
|
||||
aiData->moveLimitations[battler] = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
|
||||
aiData->speedStats[battler] = GetBattlerTotalSpeedStatArgs(battler, ability, holdEffect);
|
||||
aiData->speedStats[battler] = GetBattlerTotalSpeedStat(battler, ability, holdEffect);
|
||||
|
||||
if (IsAiBattlerAssumingStab())
|
||||
RecordMovesBasedOnStab(battler);
|
||||
|
|
@ -3004,6 +3004,19 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
return score;
|
||||
}
|
||||
|
||||
static s32 AI_GetWhichBattlerFasterOrTies(u32 battlerAtk, u32 battlerDef, bool32 ignoreChosenMoves)
|
||||
{
|
||||
struct BattleContext ctx = {0};
|
||||
ctx.battlerAtk = battlerAtk;
|
||||
ctx.battlerDef = battlerDef;
|
||||
ctx.abilities[battlerAtk] = gAiLogicData->abilities[battlerAtk];
|
||||
ctx.abilities[battlerDef] = gAiLogicData->abilities[battlerDef];
|
||||
ctx.holdEffects[battlerAtk] = gAiLogicData->holdEffects[battlerAtk];
|
||||
ctx.holdEffects[battlerDef] = gAiLogicData->holdEffects[battlerDef];
|
||||
|
||||
return GetWhichBattlerFasterOrTies(&ctx, ignoreChosenMoves);
|
||||
}
|
||||
|
||||
static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
{
|
||||
u32 movesetIndex = gAiThinkingStruct->movesetIndex;
|
||||
|
|
@ -3025,7 +3038,7 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||
ADJUST_SCORE(SLOW_KILL);
|
||||
}
|
||||
else if (CanTargetFaintAi(battlerDef, battlerAtk)
|
||||
&& GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) != AI_IS_FASTER
|
||||
&& AI_GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) != AI_IS_FASTER
|
||||
&& GetBattleMovePriority(battlerAtk, gAiLogicData->abilities[battlerAtk], move) > 0)
|
||||
{
|
||||
if (RandomPercentage(RNG_AI_PRIORITIZE_LAST_CHANCE, PRIORITIZE_LAST_CHANCE_CHANCE))
|
||||
|
|
@ -5059,7 +5072,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru
|
|||
if (IsStatBoostingBerry(item) && aiData->hpPercents[battlerAtk] > 60)
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
else if (ShouldRestoreHpBerry(battlerAtk, item) && !CanAIFaintTarget(battlerAtk, battlerDef, 0)
|
||||
&& ((GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) == 1 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0))
|
||||
&& ((AI_GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) == 1 && CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 0))
|
||||
|| !CanTargetFaintAiWithMod(battlerDef, battlerAtk, toHeal, 0)))
|
||||
ADJUST_SCORE(WEAK_EFFECT); // Recycle healing berry if we can't otherwise faint the target and the target wont kill us after we activate the berry
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1374,8 +1374,8 @@ s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler, u32 aiMoveConsidered, u32 pla
|
|||
return AI_IS_SLOWER;
|
||||
}
|
||||
|
||||
speedBattlerAI = GetBattlerTotalSpeedStatArgs(battlerAI, abilityAI, holdEffectAI);
|
||||
speedBattler = GetBattlerTotalSpeedStatArgs(battler, abilityPlayer, holdEffectPlayer);
|
||||
speedBattlerAI = GetBattlerTotalSpeedStat(battlerAI, abilityAI, holdEffectAI);
|
||||
speedBattler = GetBattlerTotalSpeedStat(battler, abilityPlayer, holdEffectPlayer);
|
||||
|
||||
if (holdEffectAI == HOLD_EFFECT_LAGGING_TAIL && holdEffectPlayer != HOLD_EFFECT_LAGGING_TAIL)
|
||||
return AI_IS_SLOWER;
|
||||
|
|
|
|||
|
|
@ -121,15 +121,21 @@ static bool32 HandleEndTurnOrder(u32 battler)
|
|||
gBattleStruct->endTurnEventsCounter++;
|
||||
|
||||
u32 i, j;
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gBattlerByTurnOrder[i] = i;
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
if (GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE) == -1)
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
|
||||
if (GetWhichBattlerFaster(&ctx, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
#include "battle_scripts.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tower.h"
|
||||
#include "battle_util.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "battle_gimmick.h"
|
||||
#include "berry.h"
|
||||
|
|
@ -112,7 +111,7 @@ static void SetActionsAndBattlersTurnOrder(void);
|
|||
static void UpdateBattlerPartyOrdersOnSwitch(u32 battler);
|
||||
static bool8 AllAtActionConfirmed(void);
|
||||
static void TryChangeTurnOrder(void);
|
||||
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2, u32 *quickClawRandom, u32 *quickDrawRandom);
|
||||
static void TryChangingTurnOrderEffects(struct BattleContext *ctx, u32 *quickClawRandom, u32 *quickDrawRandom);
|
||||
static void CheckChangingTurnOrderEffects(void);
|
||||
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
|
||||
static void ReturnFromBattleToOverworld(void);
|
||||
|
|
@ -3801,13 +3800,21 @@ static void TryDoEventsBeforeFirstTurn(void)
|
|||
gBattleStruct->speedTieBreaks = RandomUniform(RNG_SPEED_TIE, 0, Factorial(MAX_BATTLERS_COUNT) - 1);
|
||||
gBattleTurnCounter = 0;
|
||||
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
gBattlerByTurnOrder[i] = i;
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
if (GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], TRUE) == -1)
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
|
||||
if (GetWhichBattlerFaster(&ctx, TRUE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
|
|
@ -4759,7 +4766,7 @@ void SwapTurnOrder(u8 id1, u8 id2)
|
|||
}
|
||||
|
||||
// For AI, so it doesn't 'cheat' by knowing player's ability
|
||||
u32 GetBattlerTotalSpeedStatArgs(u32 battler, enum Ability ability, enum HoldEffect holdEffect)
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler, enum Ability ability, enum HoldEffect holdEffect)
|
||||
{
|
||||
u32 speed = gBattleMons[battler].speed;
|
||||
|
||||
|
|
@ -4826,13 +4833,6 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, enum Ability ability, enum HoldEff
|
|||
return speed;
|
||||
}
|
||||
|
||||
u32 GetBattlerTotalSpeedStat(u32 battler)
|
||||
{
|
||||
enum Ability ability = GetBattlerAbility(battler);
|
||||
enum HoldEffect holdEffect = GetBattlerHoldEffect(battler);
|
||||
return GetBattlerTotalSpeedStatArgs(battler, ability, holdEffect);
|
||||
}
|
||||
|
||||
s32 GetChosenMovePriority(u32 battler, enum Ability ability)
|
||||
{
|
||||
u16 move;
|
||||
|
|
@ -4886,8 +4886,7 @@ s32 GetBattleMovePriority(u32 battler, enum Ability ability, u32 move)
|
|||
return priority;
|
||||
}
|
||||
|
||||
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, enum Ability ability1, enum Ability ability2,
|
||||
enum HoldEffect holdEffectBattler1, enum HoldEffect holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2)
|
||||
s32 GetWhichBattlerFasterArgs(struct BattleContext *ctx, bool32 ignoreChosenMoves, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2)
|
||||
{
|
||||
u32 strikesFirst = 0;
|
||||
|
||||
|
|
@ -4896,18 +4895,18 @@ s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
|
|||
// Quick Claw / Quick Draw / Custap Berry - always first
|
||||
// Stall / Mycelium Might - last but before Lagging Tail
|
||||
// Lagging Tail - always last
|
||||
bool32 battler1HasQuickEffect = gProtectStructs[battler1].quickDraw || gProtectStructs[battler1].usedCustapBerry;
|
||||
bool32 battler2HasQuickEffect = gProtectStructs[battler2].quickDraw || gProtectStructs[battler2].usedCustapBerry;
|
||||
bool32 battler1HasStallingAbility = ability1 == ABILITY_STALL || gProtectStructs[battler1].myceliumMight;
|
||||
bool32 battler2HasStallingAbility = ability2 == ABILITY_STALL || gProtectStructs[battler2].myceliumMight;
|
||||
bool32 battler1HasQuickEffect = gProtectStructs[ctx->battlerAtk].quickDraw || gProtectStructs[ctx->battlerAtk].usedCustapBerry;
|
||||
bool32 battler2HasQuickEffect = gProtectStructs[ctx->battlerDef].quickDraw || gProtectStructs[ctx->battlerDef].usedCustapBerry;
|
||||
bool32 battler1HasStallingAbility = ctx->abilities[ctx->battlerAtk] == ABILITY_STALL || gProtectStructs[ctx->battlerAtk].myceliumMight;
|
||||
bool32 battler2HasStallingAbility = ctx->abilities[ctx->battlerDef] == ABILITY_STALL || gProtectStructs[ctx->battlerDef].myceliumMight;
|
||||
|
||||
if (battler1HasQuickEffect && !battler2HasQuickEffect)
|
||||
strikesFirst = 1;
|
||||
else if (battler2HasQuickEffect && !battler1HasQuickEffect)
|
||||
strikesFirst = -1;
|
||||
else if (gProtectStructs[battler1].laggingTail && !gProtectStructs[battler2].laggingTail)
|
||||
else if (gProtectStructs[ctx->battlerAtk].laggingTail && !gProtectStructs[ctx->battlerDef].laggingTail)
|
||||
strikesFirst = -1;
|
||||
else if (gProtectStructs[battler2].laggingTail && !gProtectStructs[battler1].laggingTail)
|
||||
else if (gProtectStructs[ctx->battlerDef].laggingTail && !gProtectStructs[ctx->battlerAtk].laggingTail)
|
||||
strikesFirst = 1;
|
||||
else if (battler1HasStallingAbility && !battler2HasStallingAbility)
|
||||
strikesFirst = -1;
|
||||
|
|
@ -4949,32 +4948,27 @@ s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
|
|||
return strikesFirst;
|
||||
}
|
||||
|
||||
s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves)
|
||||
s32 GetWhichBattlerFasterOrTies(struct BattleContext *ctx, bool32 ignoreChosenMoves)
|
||||
{
|
||||
s32 priority1 = 0, priority2 = 0;
|
||||
enum Ability ability1 = GetBattlerAbility(battler1);
|
||||
u32 speedBattler1 = GetBattlerTotalSpeedStat(battler1);
|
||||
enum HoldEffect holdEffectBattler1 = GetBattlerHoldEffect(battler1);
|
||||
u32 speedBattler2 = GetBattlerTotalSpeedStat(battler2);
|
||||
enum HoldEffect holdEffectBattler2 = GetBattlerHoldEffect(battler2);
|
||||
enum Ability ability2 = GetBattlerAbility(battler2);
|
||||
u32 speedBattler1 = GetBattlerTotalSpeedStat(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ctx->holdEffects[ctx->battlerAtk]);
|
||||
u32 speedBattler2 = GetBattlerTotalSpeedStat(ctx->battlerDef, ctx->abilities[ctx->battlerDef], ctx->holdEffects[ctx->battlerDef]);
|
||||
|
||||
if (!ignoreChosenMoves)
|
||||
{
|
||||
if (gChosenActionByBattler[battler1] == B_ACTION_USE_MOVE)
|
||||
priority1 = GetChosenMovePriority(battler1, ability1);
|
||||
if (gChosenActionByBattler[battler2] == B_ACTION_USE_MOVE)
|
||||
priority2 = GetChosenMovePriority(battler2, ability2);
|
||||
if (gChosenActionByBattler[ctx->battlerAtk] == B_ACTION_USE_MOVE)
|
||||
priority1 = GetChosenMovePriority(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk]);
|
||||
if (gChosenActionByBattler[ctx->battlerDef] == B_ACTION_USE_MOVE)
|
||||
priority2 = GetChosenMovePriority(ctx->battlerDef, ctx->abilities[ctx->battlerDef]);
|
||||
}
|
||||
|
||||
return GetWhichBattlerFasterArgs(
|
||||
battler1, battler2,
|
||||
ctx,
|
||||
ignoreChosenMoves,
|
||||
ability1, ability2,
|
||||
holdEffectBattler1, holdEffectBattler2,
|
||||
speedBattler1, speedBattler2,
|
||||
priority1, priority2
|
||||
);
|
||||
speedBattler1,
|
||||
speedBattler2,
|
||||
priority1,
|
||||
priority2);
|
||||
}
|
||||
|
||||
// 24 == MAX_BATTLERS_COUNT!.
|
||||
|
|
@ -5008,13 +5002,13 @@ static const u8 sBattlerOrders[24][4] =
|
|||
{ 3, 2, 1, 0 },
|
||||
};
|
||||
|
||||
s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves)
|
||||
s32 GetWhichBattlerFaster(struct BattleContext *ctx, bool32 ignoreChosenMoves)
|
||||
{
|
||||
s32 strikesFirst = GetWhichBattlerFasterOrTies(battler1, battler2, ignoreChosenMoves);
|
||||
s32 strikesFirst = GetWhichBattlerFasterOrTies(ctx, ignoreChosenMoves);
|
||||
if (strikesFirst == 0)
|
||||
{
|
||||
s32 order1 = sBattlerOrders[gBattleStruct->speedTieBreaks][battler1];
|
||||
s32 order2 = sBattlerOrders[gBattleStruct->speedTieBreaks][battler2];
|
||||
s32 order1 = sBattlerOrders[gBattleStruct->speedTieBreaks][ctx->battlerAtk];
|
||||
s32 order2 = sBattlerOrders[gBattleStruct->speedTieBreaks][ctx->battlerDef];
|
||||
if (order1 < order2)
|
||||
strikesFirst = 1;
|
||||
else
|
||||
|
|
@ -5108,13 +5102,19 @@ static void SetActionsAndBattlersTurnOrder(void)
|
|||
turnOrderId++;
|
||||
}
|
||||
}
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
for (i = 0; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u8 battler1 = gBattlerByTurnOrder[i];
|
||||
u8 battler2 = gBattlerByTurnOrder[j];
|
||||
TryChangingTurnOrderEffects(battler1, battler2, quickClawRandom, quickDrawRandom);
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
TryChangingTurnOrderEffects(&ctx, quickClawRandom, quickDrawRandom);
|
||||
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
|
||||
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
|
||||
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
|
||||
|
|
@ -5122,7 +5122,7 @@ static void SetActionsAndBattlersTurnOrder(void)
|
|||
&& gActionsByTurnOrder[i] != B_ACTION_THROW_BALL
|
||||
&& gActionsByTurnOrder[j] != B_ACTION_THROW_BALL)
|
||||
{
|
||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
||||
if (GetWhichBattlerFaster(&ctx, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
|
|
@ -5270,29 +5270,38 @@ static bool32 TryDoMoveEffectsBeforeMoves(void)
|
|||
static void TryChangeTurnOrder(void)
|
||||
{
|
||||
u32 i, j;
|
||||
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u32 battler1 = gBattlerByTurnOrder[i];
|
||||
u32 battler2 = gBattlerByTurnOrder[j];
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
|
||||
if (gActionsByTurnOrder[i] == B_ACTION_USE_MOVE
|
||||
&& gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)
|
||||
{
|
||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
||||
if (GetWhichBattlerFaster(&ctx, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2, u32 *quickClawRandom, u32 *quickDrawRandom)
|
||||
static void TryChangingTurnOrderEffects(struct BattleContext *ctx, u32 *quickClawRandom, u32 *quickDrawRandom)
|
||||
{
|
||||
enum Ability ability1 = GetBattlerAbility(battler1);
|
||||
enum HoldEffect holdEffectBattler1 = GetBattlerHoldEffect(battler1);
|
||||
enum HoldEffect holdEffectBattler2 = GetBattlerHoldEffect(battler2);
|
||||
enum Ability ability2 = GetBattlerAbility(battler2);
|
||||
u32 battler1 = ctx->battlerAtk;
|
||||
u32 battler2 = ctx->battlerDef;
|
||||
enum Ability ability1 = ctx->abilities[ctx->battlerAtk];
|
||||
enum Ability ability2 = ctx->abilities[ctx->battlerDef];
|
||||
enum HoldEffect holdEffectBattler1 = ctx->holdEffects[ctx->battlerAtk];
|
||||
enum HoldEffect holdEffectBattler2 = ctx->holdEffects[ctx->battlerDef];
|
||||
|
||||
// Battler 1
|
||||
// Quick Draw
|
||||
|
|
|
|||
|
|
@ -15563,13 +15563,22 @@ void BS_TryQuash(void)
|
|||
// If the above condition is not true, it means we are faster than the foe, so we can set the quash bit
|
||||
gProtectStructs[gBattlerTarget].quash = TRUE;
|
||||
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
// this implementation assumes turn order is correct when using Quash
|
||||
i = GetBattlerTurnOrderNum(gBattlerTarget);
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
|
||||
// Gen 7- config makes target go last so that the order of quash targets is kept for the correct turn order
|
||||
// Gen 8+ config alters Turn Order of the target according to speed, dynamic speed should handle the rest
|
||||
if (B_QUASH_TURN_ORDER < GEN_8 || GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE) == -1)
|
||||
if (B_QUASH_TURN_ORDER < GEN_8 || GetWhichBattlerFaster(&ctx, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
else
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -953,27 +953,34 @@ void HandleAction_ActionFinished(void)
|
|||
{
|
||||
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
|
||||
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
|
||||
|
||||
struct BattleContext ctx = {0};
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
ctx.abilities[i] = GetBattlerAbility(i);
|
||||
ctx.holdEffects[i] = GetBattlerHoldEffect(i);
|
||||
}
|
||||
for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++)
|
||||
{
|
||||
for (j = i + 1; j < gBattlersCount; j++)
|
||||
{
|
||||
u32 battler1 = gBattlerByTurnOrder[i];
|
||||
u32 battler2 = gBattlerByTurnOrder[j];
|
||||
ctx.battlerAtk = gBattlerByTurnOrder[i];
|
||||
ctx.battlerDef = gBattlerByTurnOrder[j];
|
||||
|
||||
if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash
|
||||
|| gProtectStructs[battler1].shellTrap || gProtectStructs[battler2].shellTrap)
|
||||
if (gProtectStructs[ctx.battlerAtk].quash || gProtectStructs[ctx.battlerDef].quash
|
||||
|| gProtectStructs[ctx.battlerAtk].shellTrap || gProtectStructs[ctx.battlerDef].shellTrap)
|
||||
continue;
|
||||
|
||||
// We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should
|
||||
// have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder
|
||||
if ((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE))
|
||||
{
|
||||
if (GetWhichBattlerFaster(battler1, battler2, FALSE) == -1)
|
||||
if (GetWhichBattlerFaster(&ctx, FALSE) == -1)
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
else if ((gActionsByTurnOrder[i] == B_ACTION_SWITCH && gActionsByTurnOrder[j] == B_ACTION_SWITCH))
|
||||
{
|
||||
if (GetWhichBattlerFaster(battler1, battler2, TRUE) == -1) // If the actions chosen are switching, we recalc order but ignoring the moves
|
||||
if (GetWhichBattlerFaster(&ctx, TRUE) == -1) // If the actions chosen are switching, we recalc order but ignoring the moves
|
||||
SwapTurnOrder(i, j);
|
||||
}
|
||||
}
|
||||
|
|
@ -6948,21 +6955,21 @@ static inline u32 CalcMoveBasePower(struct DamageContext *ctx)
|
|||
basePower += (CountBattlerStatIncreases(battlerAtk, TRUE) * 20);
|
||||
break;
|
||||
case EFFECT_ELECTRO_BALL:
|
||||
speed = GetBattlerTotalSpeedStat(battlerAtk) / GetBattlerTotalSpeedStat(battlerDef);
|
||||
speed = GetBattlerTotalSpeedStat(battlerAtk, ctx->abilityAtk, ctx->holdEffectAtk) / GetBattlerTotalSpeedStat(battlerDef, ctx->abilityDef, ctx->holdEffectDef);
|
||||
if (speed >= ARRAY_COUNT(sSpeedDiffPowerTable))
|
||||
speed = ARRAY_COUNT(sSpeedDiffPowerTable) - 1;
|
||||
basePower = sSpeedDiffPowerTable[speed];
|
||||
break;
|
||||
case EFFECT_GYRO_BALL:
|
||||
{
|
||||
u32 attackerSpeed = GetBattlerTotalSpeedStat(battlerAtk);
|
||||
u32 attackerSpeed = GetBattlerTotalSpeedStat(battlerAtk, ctx->abilityAtk, ctx->holdEffectAtk);
|
||||
if (attackerSpeed == 0)
|
||||
{
|
||||
basePower = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
basePower = ((25 * GetBattlerTotalSpeedStat(battlerDef)) / attackerSpeed) + 1;
|
||||
basePower = ((25 * GetBattlerTotalSpeedStat(battlerDef, ctx->abilityDef, ctx->holdEffectDef)) / attackerSpeed) + 1;
|
||||
if (basePower > 150)
|
||||
basePower = 150;
|
||||
}
|
||||
|
|
@ -9511,7 +9518,10 @@ void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast)
|
|||
u16 speeds[MAX_BATTLERS_COUNT] = {0};
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
speeds[i] = GetBattlerTotalSpeedStat(battlers[i]);
|
||||
{
|
||||
u32 battler = battlers[i];
|
||||
speeds[i] = GetBattlerTotalSpeedStat(battler, GetBattlerAbility(battler), GetBattlerHoldEffect(battler));
|
||||
}
|
||||
|
||||
for (i = 1; i < gBattlersCount; i++)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user