Fixes Quick Draw (#3724)

* Fixes Quick Draw

* Fixes Custap and rest of Quick Draw

* review applied
This commit is contained in:
Alex 2023-12-15 00:03:59 +01:00 committed by GitHub
parent 03e2571214
commit be045fdc0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 31 deletions

View file

@ -982,7 +982,6 @@ extern u32 gStatuses4[MAX_BATTLERS_COUNT];
extern struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT];
extern u16 gPauseCounterBattle;
extern u16 gPaydayMoney;
extern u16 gRandomTurnNumber;
extern u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT];
extern u8 gBattleOutcome;
extern struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT];

View file

@ -93,6 +93,7 @@ enum RandomTag
RNG_TRIPLE_ARROWS_DEFENSE_DOWN,
RNG_TRIPLE_ARROWS_FLINCH,
RNG_QUICK_DRAW,
RNG_QUICK_CLAW,
RNG_TRACE,
};

View file

@ -105,7 +105,8 @@ static bool8 AllAtActionConfirmed(void);
static void TryChangeTurnOrder(void);
static void CheckChosenMoveForEffectsBeforeTurnStarts(void);
static void CheckMegaEvolutionBeforeTurn(void);
static void CheckQuickClaw_CustapBerryActivation(void);
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2);
static void CheckChangingTurnOrderEffects(void);
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
static void ReturnFromBattleToOverworld(void);
static void TryEvolvePokemon(void);
@ -203,7 +204,6 @@ EWRAM_DATA u32 gStatuses4[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gPauseCounterBattle = 0;
EWRAM_DATA u16 gPaydayMoney = 0;
EWRAM_DATA u16 gRandomTurnNumber = 0;
EWRAM_DATA u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT] = {0};
EWRAM_DATA u8 gBattleOutcome = 0;
EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0};
@ -3096,8 +3096,6 @@ static void BattleStartClearSetData(void)
gBattleStruct->givenExpMons = 0;
gBattleStruct->palaceFlags = 0;
gRandomTurnNumber = Random();
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
gBattleStruct->arenaLostPlayerMons = 0;
@ -3854,8 +3852,6 @@ static void TryDoEventsBeforeFirstTurn(void)
gBattleStruct->turnCountersTracker = 0;
gMoveResultFlags = 0;
gRandomTurnNumber = Random();
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
@ -3950,7 +3946,6 @@ void BattleTurnPassed(void)
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
gBattleMainFunc = HandleTurnActionSelectionState;
gRandomTurnNumber = Random();
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
BattleScriptExecute(BattleScript_PalacePrintFlavorText);
@ -4746,26 +4741,6 @@ u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
{
u32 strikesFirst = 0;
// Battler 1
// Quick Draw
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && RandomPercentage(RNG_QUICK_DRAW, 30))
gProtectStructs[battler1].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler1].quickDraw
&& ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
|| (holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item))))
gProtectStructs[battler1].usedCustapBerry = TRUE;
// Battler 2
// Quick Draw
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && RandomPercentage(RNG_QUICK_DRAW, 30))
gProtectStructs[battler2].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler2].quickDraw
&& ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
|| (holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
gProtectStructs[battler2].usedCustapBerry = TRUE;
if (priority1 == priority2)
{
// QUICK CLAW / CUSTAP - always first
@ -4936,6 +4911,7 @@ static void SetActionsAndBattlersTurnOrder(void)
{
u8 battler1 = gBattlerByTurnOrder[i];
u8 battler2 = gBattlerByTurnOrder[j];
TryChangingTurnOrderEffects(battler1, battler2);
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
@ -4950,7 +4926,7 @@ static void SetActionsAndBattlersTurnOrder(void)
}
}
}
gBattleMainFunc = CheckQuickClaw_CustapBerryActivation;
gBattleMainFunc = CheckChangingTurnOrderEffects;
gBattleStruct->quickClawBattlerId = 0;
}
@ -4968,6 +4944,7 @@ static void TurnValuesCleanUp(bool8 var0)
gProtectStructs[i].banefulBunkered = FALSE;
gProtectStructs[i].quash = FALSE;
gProtectStructs[i].usedCustapBerry = FALSE;
gProtectStructs[i].quickDraw = FALSE;
}
else
{
@ -5115,7 +5092,37 @@ static void TryChangeTurnOrder(void)
}
}
static void CheckQuickClaw_CustapBerryActivation(void)
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2)
{
u32 ability1 = GetBattlerAbility(battler1);
u32 speedBattler1 = GetBattlerTotalSpeedStat(battler1);
u32 holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
u32 speedBattler2 = GetBattlerTotalSpeedStat(battler2);
u32 holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
u32 ability2 = GetBattlerAbility(battler2);
// Battler 1
// Quick Draw
if (ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && RandomPercentage(RNG_QUICK_DRAW, 30))
gProtectStructs[battler1].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler1].quickDraw
&& ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && RandomPercentage(RNG_QUICK_CLAW, 10))
|| (holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item))))
gProtectStructs[battler1].usedCustapBerry = TRUE;
// Battler 2
// Quick Draw
if (ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && RandomPercentage(RNG_QUICK_DRAW, 30))
gProtectStructs[battler2].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler2].quickDraw
&& ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && RandomPercentage(RNG_QUICK_CLAW, 10))
|| (holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
gProtectStructs[battler2].usedCustapBerry = TRUE;
}
static void CheckChangingTurnOrderEffects(void)
{
u32 i, battler;
@ -5150,7 +5157,6 @@ static void CheckQuickClaw_CustapBerryActivation(void)
else if (gProtectStructs[battler].quickDraw)
{
gBattlerAbility = battler;
gProtectStructs[battler].quickDraw = FALSE;
gLastUsedAbility = gBattleMons[battler].ability;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
RecordAbilityBattle(battler, gLastUsedAbility);

View file

@ -15,3 +15,18 @@ SINGLE_BATTLE_TEST("Quick Draw has a 30% chance of going first")
MESSAGE("Foe Wobbuffet used Celebrate!");
}
}
SINGLE_BATTLE_TEST("Quick Draw does not activate 70% of the time")
{
PASSES_RANDOMLY(7, 10, RNG_QUICK_DRAW);
GIVEN {
PLAYER(SPECIES_SLOWBRO_GALARIAN) { Ability(ABILITY_QUICK_DRAW); Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
} WHEN {
TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_TACKLE); }
} SCENE {
NOT ABILITY_POPUP(player, ABILITY_QUICK_DRAW);
MESSAGE("Foe Wobbuffet used Celebrate!");
MESSAGE("Slowbro used Tackle!");
}
}

View file

@ -35,3 +35,17 @@ SINGLE_BATTLE_TEST("Custap Berry allows the holder to move first in its priority
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
}
}
SINGLE_BATTLE_TEST("Custap Berry activates even if the opposing mon switches out")
{
GIVEN {
PLAYER(SPECIES_REGIROCK) { HP(1); Item(ITEM_CUSTAP_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(opponent, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Regirock can act faster, thanks to Custap Berry!");
}
}

View file

@ -0,0 +1,21 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gItems[ITEM_QUICK_CLAW].holdEffect == HOLD_EFFECT_QUICK_CLAW);
}
SINGLE_BATTLE_TEST("Quick Claw activates 10% of the time")
{
PASSES_RANDOMLY(1, 10, RNG_QUICK_CLAW);
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(1); Item(ITEM_QUICK_CLAW); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
MESSAGE("Wobbuffet used Tackle!");
MESSAGE("Foe Wobbuffet used Celebrate!");
}
}