Fix Quick Guard

This commit is contained in:
DizzyEggg 2018-12-22 15:10:24 +01:00
parent 0748069705
commit f7a7ddde0c
9 changed files with 103 additions and 61 deletions

View File

@ -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) \

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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!");

View File

@ -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;

View File

@ -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)

View File

@ -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] =