mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-26 21:33:53 +01:00
Fix Quick Guard
This commit is contained in:
parent
0748069705
commit
f7a7ddde0c
@ -177,8 +177,6 @@ struct DisableStruct
|
||||
struct ProtectStruct
|
||||
{
|
||||
u32 protected:1;
|
||||
u32 wideGuarded:1;
|
||||
u32 quickGuarded:1;
|
||||
u32 spikyShielded:1;
|
||||
u32 kingsShielded:1;
|
||||
u32 banefulBunkered:1;
|
||||
@ -589,7 +587,6 @@ struct BattleStruct
|
||||
struct MegaEvolutionData mega;
|
||||
const u8 *trainerSlideMsg;
|
||||
bool8 trainerSlideLowHpMsgDone;
|
||||
s8 movePriorities[MAX_BATTLERS_COUNT];
|
||||
};
|
||||
|
||||
#define GET_MOVE_TYPE(move, typeArg) \
|
||||
|
@ -80,6 +80,7 @@ u8 IsRunningFromBattleImpossible(void);
|
||||
void sub_803BDA0(u8 battlerId);
|
||||
void SwapTurnOrder(u8 id1, u8 id2);
|
||||
u32 GetBattlerTotalSpeedStat(u8 battlerId);
|
||||
s8 GetMovePriority(u8 battlerId);
|
||||
u8 GetWhoStrikesFirst(u8 battlerId1, u8 battlerId2, bool8 ignoreChosenMoves);
|
||||
void RunBattleScriptCommands_PopCallbacksStack(void);
|
||||
void RunBattleScriptCommands(void);
|
||||
|
@ -209,6 +209,8 @@
|
||||
#define SIDE_STATUS_STEALTH_ROCK_DAMAGED (1 << 15)
|
||||
#define SIDE_STATUS_TOXIC_SPIKES_DAMAGED (1 << 16)
|
||||
#define SIDE_STATUS_STICKY_WEB_DAMAGED (1 << 17)
|
||||
#define SIDE_STATUS_QUICK_GUARD (1 << 18)
|
||||
#define SIDE_STATUS_WIDE_GUARD (1 << 18)
|
||||
|
||||
// Field affecting statuses.
|
||||
#define STATUS_FIELD_MAGIC_ROOM 0x1
|
||||
|
@ -109,6 +109,7 @@ enum
|
||||
VAR_SHOW_HP,
|
||||
VAR_SUBSTITUTE,
|
||||
VAR_IN_LOVE,
|
||||
VAR_U16_4_ENTRIES,
|
||||
};
|
||||
|
||||
enum
|
||||
@ -855,6 +856,8 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data)
|
||||
itemsCount = 3;
|
||||
break;
|
||||
case LIST_ITEM_MOVES:
|
||||
itemsCount = 5;
|
||||
break;
|
||||
case LIST_ITEM_PP:
|
||||
itemsCount = 4;
|
||||
break;
|
||||
@ -958,6 +961,15 @@ static void PrintSecondaryEntries(struct BattleDebugMenu *data)
|
||||
printer.currentY = printer.y = (i * yMultiplier) + sSecondaryListTemplate.upText_Y;
|
||||
AddTextPrinter(&printer, 0, NULL);
|
||||
}
|
||||
// Allow changing all moves at once. Useful for testing in wild doubles.
|
||||
if (data->currentMainListItemId == LIST_ITEM_MOVES)
|
||||
{
|
||||
u8 textAll[] = _("All");
|
||||
|
||||
PadString(textAll, text);
|
||||
printer.currentY = printer.y = (i * yMultiplier) + sSecondaryListTemplate.upText_Y;
|
||||
AddTextPrinter(&printer, 0, NULL);
|
||||
}
|
||||
break;
|
||||
case LIST_ITEM_ABILITY:
|
||||
PadString(gAbilityNames[gBattleMons[data->battlerId].ability], text);
|
||||
@ -1052,6 +1064,12 @@ static void UpdateBattlerValue(struct BattleDebugMenu *data)
|
||||
case VAL_U16:
|
||||
*(u16*)(data->modifyArrows.modifiedValPtr) = data->modifyArrows.currValue;
|
||||
break;
|
||||
case VAR_U16_4_ENTRIES:
|
||||
((u16*)(data->modifyArrows.modifiedValPtr))[0] = data->modifyArrows.currValue;
|
||||
((u16*)(data->modifyArrows.modifiedValPtr))[1] = data->modifyArrows.currValue;
|
||||
((u16*)(data->modifyArrows.modifiedValPtr))[2] = data->modifyArrows.currValue;
|
||||
((u16*)(data->modifyArrows.modifiedValPtr))[3] = data->modifyArrows.currValue;
|
||||
break;
|
||||
case VAL_U32:
|
||||
*(u32*)(data->modifyArrows.modifiedValPtr) = data->modifyArrows.currValue;
|
||||
break;
|
||||
@ -1273,9 +1291,18 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data)
|
||||
data->modifyArrows.minValue = 0;
|
||||
data->modifyArrows.maxValue = MOVES_COUNT_GEN7 - 1;
|
||||
data->modifyArrows.maxDigits = 3;
|
||||
data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].moves[data->currentSecondaryListItemId];
|
||||
data->modifyArrows.typeOfVal = VAL_U16;
|
||||
data->modifyArrows.currValue = gBattleMons[data->battlerId].moves[data->currentSecondaryListItemId];
|
||||
if (data->currentSecondaryListItemId == 4)
|
||||
{
|
||||
data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].moves[0];
|
||||
data->modifyArrows.currValue = gBattleMons[data->battlerId].moves[0];
|
||||
data->modifyArrows.typeOfVal = VAR_U16_4_ENTRIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].moves[data->currentSecondaryListItemId];
|
||||
data->modifyArrows.currValue = gBattleMons[data->battlerId].moves[data->currentSecondaryListItemId];
|
||||
data->modifyArrows.typeOfVal = VAL_U16;
|
||||
}
|
||||
break;
|
||||
case LIST_ITEM_PP:
|
||||
data->modifyArrows.minValue = 0;
|
||||
|
@ -3238,8 +3238,6 @@ void FaintClearSetData(void)
|
||||
ptr[i] = 0;
|
||||
|
||||
gProtectStructs[gActiveBattler].protected = 0;
|
||||
gProtectStructs[gActiveBattler].wideGuarded = 0;
|
||||
gProtectStructs[gActiveBattler].quickGuarded = 0;
|
||||
gProtectStructs[gActiveBattler].spikyShielded = 0;
|
||||
gProtectStructs[gActiveBattler].kingsShielded = 0;
|
||||
gProtectStructs[gActiveBattler].banefulBunkered = 0;
|
||||
@ -4711,8 +4709,9 @@ u32 GetBattlerTotalSpeedStat(u8 battlerId)
|
||||
return speed;
|
||||
}
|
||||
|
||||
static s8 GetMovePriority(u8 battlerId)
|
||||
s8 GetMovePriority(u8 battlerId)
|
||||
{
|
||||
s8 priority;
|
||||
u16 move;
|
||||
|
||||
if (gProtectStructs[battlerId].noValidMoves)
|
||||
@ -4720,17 +4719,17 @@ static s8 GetMovePriority(u8 battlerId)
|
||||
else
|
||||
move = gBattleMons[battlerId].moves[*(gBattleStruct->chosenMovePositions + battlerId)];
|
||||
|
||||
gBattleStruct->movePriorities[battlerId] = gBattleMoves[move].priority;
|
||||
priority = gBattleMoves[move].priority;
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_GALE_WINGS
|
||||
&& gBattleMoves[move].type == TYPE_FLYING
|
||||
&& (B_GALE_WINGS == GEN_6 || BATTLER_MAX_HP(battlerId)))
|
||||
{
|
||||
gBattleStruct->movePriorities[battlerId]++;
|
||||
priority++;
|
||||
}
|
||||
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER
|
||||
&& gBattleMoves[move].split == SPLIT_STATUS)
|
||||
{
|
||||
gBattleStruct->movePriorities[battlerId]++;
|
||||
priority++;
|
||||
}
|
||||
else if (GetBattlerAbility(battlerId) == ABILITY_TRIAGE)
|
||||
{
|
||||
@ -4748,12 +4747,12 @@ static s8 GetMovePriority(u8 battlerId)
|
||||
case EFFECT_SOFTBOILED:
|
||||
case EFFECT_ABSORB:
|
||||
case EFFECT_ROOST:
|
||||
gBattleStruct->movePriorities[battlerId] += 3;
|
||||
priority += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gBattleStruct->movePriorities[battlerId];
|
||||
return priority;
|
||||
}
|
||||
|
||||
u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
|
||||
@ -4949,9 +4948,6 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||
if (var0)
|
||||
{
|
||||
gProtectStructs[gActiveBattler].protected = 0;
|
||||
gProtectStructs[gActiveBattler].endured = 0;
|
||||
gProtectStructs[gActiveBattler].wideGuarded = 0;
|
||||
gProtectStructs[gActiveBattler].quickGuarded = 0;
|
||||
gProtectStructs[gActiveBattler].spikyShielded = 0;
|
||||
gProtectStructs[gActiveBattler].kingsShielded = 0;
|
||||
gProtectStructs[gActiveBattler].banefulBunkered = 0;
|
||||
@ -4977,6 +4973,8 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE);
|
||||
}
|
||||
|
||||
gSideStatuses[0] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD);
|
||||
gSideStatuses[1] &= ~(SIDE_STATUS_QUICK_GUARD | SIDE_STATUS_WIDE_GUARD);
|
||||
gSideTimers[0].followmeTimer = 0;
|
||||
gSideTimers[1].followmeTimer = 0;
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ static const u8 sText_PointedStonesFloat[] =_("Pointed stones float in the air\n
|
||||
static const u8 sText_CloakedInMysticalMoonlight[] =_("It became cloaked in mystical\nmoonlight!");
|
||||
static const u8 sText_TrappedBySwirlingMagma[] =_("{B_DEF_NAME_WITH_PREFIX} became\ntrapped by swirling magma!");
|
||||
static const u8 sText_VanishedInstantly[] =_("{B_ATK_NAME_WITH_PREFIX} vanished\ninstantly!");
|
||||
static const u8 sText_ProtectedTeam[] =_("{B_CURRENT_MOVE} protected\nyour team!");
|
||||
static const u8 sText_ProtectedTeam[] =_("{B_CURRENT_MOVE} protected\n{B_ATK_TEAM}!");
|
||||
static const u8 sText_SharedItsGuard[] =_("{B_ATK_NAME_WITH_PREFIX} shared its\nguard with the target!");
|
||||
static const u8 sText_SharedItsPower[] =_("{B_ATK_NAME_WITH_PREFIX} shared its\npower with the target!");
|
||||
static const u8 sText_SwapsDefAndSpDefOfAllPkmn[] =_("It created a bizarre area in which\nthe Defense and Sp.Def stats are swapped!");
|
||||
|
@ -903,7 +903,7 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
return FALSE;
|
||||
else if (gProtectStructs[battlerId].protected)
|
||||
return TRUE;
|
||||
else if ((gProtectStructs[battlerId].wideGuarded || gProtectStructs[BATTLE_PARTNER(battlerId)].wideGuarded)
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
|
||||
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].banefulBunkered)
|
||||
@ -912,8 +912,8 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
return TRUE;
|
||||
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
|
||||
return TRUE;
|
||||
else if ((gProtectStructs[battlerId].quickGuarded || gProtectStructs[BATTLE_PARTNER(battlerId)].quickGuarded)
|
||||
&& gBattleStruct->movePriorities[battlerId] > 0)
|
||||
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
|
||||
&& GetMovePriority(gBattlerAttacker) > 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@ -2732,15 +2732,15 @@ void SetMoveEffect(bool8 primary, u8 certain)
|
||||
break;
|
||||
case MOVE_EFFECT_FEINT:
|
||||
if (gProtectStructs[gBattlerTarget].protected
|
||||
|| gProtectStructs[gBattlerTarget].wideGuarded
|
||||
|| gProtectStructs[gBattlerTarget].quickGuarded
|
||||
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_WIDE_GUARD
|
||||
|| gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_QUICK_GUARD
|
||||
|| gProtectStructs[gBattlerTarget].spikyShielded
|
||||
|| gProtectStructs[gBattlerTarget].kingsShielded
|
||||
|| gProtectStructs[gBattlerTarget].banefulBunkered)
|
||||
{
|
||||
gProtectStructs[gBattlerTarget].protected = 0;
|
||||
gProtectStructs[gBattlerTarget].wideGuarded = 0;
|
||||
gProtectStructs[gBattlerTarget].quickGuarded = 0;
|
||||
gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~(SIDE_STATUS_WIDE_GUARD);
|
||||
gSideStatuses[GetBattlerSide(gBattlerTarget)] &= ~(SIDE_STATUS_QUICK_GUARD);
|
||||
gProtectStructs[gBattlerTarget].spikyShielded = 0;
|
||||
gProtectStructs[gBattlerTarget].kingsShielded = 0;
|
||||
gProtectStructs[gBattlerTarget].banefulBunkered = 0;
|
||||
@ -7202,8 +7202,9 @@ static void atk76_various(void)
|
||||
gBattlescriptCurrInstr += 3;
|
||||
}
|
||||
|
||||
static void atk77_setprotectlike(void) // protect and endure
|
||||
static void atk77_setprotectlike(void)
|
||||
{
|
||||
bool32 fail = TRUE;
|
||||
bool32 notLastTurn = TRUE;
|
||||
|
||||
if (!(gBattleMoves[gLastResultingMoves[gBattlerAttacker]].flags & FLAG_PROTECTION_MOVE))
|
||||
@ -7214,44 +7215,58 @@ static void atk77_setprotectlike(void) // protect and endure
|
||||
|
||||
if (sProtectSuccessRates[gDisableStructs[gBattlerAttacker].protectUses] >= Random() && notLastTurn)
|
||||
{
|
||||
if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE)
|
||||
if (!gBattleMoves[gCurrentMove].argument) // Protects one mon only.
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].endured = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].endured = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_DETECT || gCurrentMove == MOVE_PROTECT)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].protected = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_SPIKY_SHIELD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].spikyShielded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_KING_S_SHIELD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].kingsShielded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_BANEFUL_BUNKER)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].banefulBunkered = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
|
||||
gDisableStructs[gBattlerAttacker].protectUses++;
|
||||
fail = FALSE;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_DETECT || gCurrentMove == MOVE_PROTECT)
|
||||
else // Protects the whole side.
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].protected = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
u8 side = GetBattlerSide(gBattlerAttacker);
|
||||
if (gCurrentMove == MOVE_WIDE_GUARD && !(gSideStatuses[side] & SIDE_STATUS_WIDE_GUARD))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_WIDE_GUARD;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
gDisableStructs[gBattlerAttacker].protectUses++;
|
||||
fail = FALSE;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_QUICK_GUARD && !(gSideStatuses[side] & SIDE_STATUS_QUICK_GUARD))
|
||||
{
|
||||
gSideStatuses[side] |= SIDE_STATUS_QUICK_GUARD;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
gDisableStructs[gBattlerAttacker].protectUses++;
|
||||
fail = FALSE;
|
||||
}
|
||||
}
|
||||
else if (gCurrentMove == MOVE_SPIKY_SHIELD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].spikyShielded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_KING_S_SHIELD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].kingsShielded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_BANEFUL_BUNKER)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].banefulBunkered = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_WIDE_GUARD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].wideGuarded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
}
|
||||
else if (gCurrentMove == MOVE_QUICK_GUARD)
|
||||
{
|
||||
gProtectStructs[gBattlerAttacker].quickGuarded = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
}
|
||||
gDisableStructs[gBattlerAttacker].protectUses++;
|
||||
}
|
||||
else
|
||||
|
||||
if (fail)
|
||||
{
|
||||
gDisableStructs[gBattlerAttacker].protectUses = 0;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||||
|
@ -2319,7 +2319,7 @@ u8 AtkCanceller_UnableToUseMove2(void)
|
||||
case CANCELLER_PSYCHIC_TERRAIN:
|
||||
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
|
||||
&& IsBattlerGrounded(gBattlerAttacker)
|
||||
&& gBattleStruct->movePriorities[gBattlerAttacker] > 0
|
||||
&& GetMovePriority(gBattlerAttacker) > 0
|
||||
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
CancelMultiTurnMoves(gBattlerAttacker);
|
||||
@ -2899,7 +2899,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
|
||||
else if ((gLastUsedAbility == ABILITY_DAZZLING
|
||||
|| (IsBattlerAlive(battler ^= BIT_FLANK) && GetBattlerAbility(battler) == ABILITY_DAZZLING)
|
||||
)
|
||||
&& gBattleStruct->movePriorities[gBattlerAttacker] > 0
|
||||
&& GetMovePriority(battler) > 0
|
||||
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(battler))
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
|
||||
|
@ -6587,6 +6587,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.priority = 3,
|
||||
.flags = FLAG_PROTECTION_MOVE,
|
||||
.split = SPLIT_STATUS,
|
||||
.argument = TRUE, // Protects the whole side.
|
||||
},
|
||||
|
||||
[MOVE_GUARD_SPLIT] =
|
||||
@ -7035,6 +7036,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
||||
.priority = 3,
|
||||
.flags = FLAG_PROTECTION_MOVE,
|
||||
.split = SPLIT_STATUS,
|
||||
.argument = TRUE, // Protects the whole side.
|
||||
},
|
||||
|
||||
[MOVE_ALLY_SWITCH] =
|
||||
|
Loading…
x
Reference in New Issue
Block a user