Adds Gen5+ Encore config (#7051)

This commit is contained in:
Alex 2025-06-25 15:58:30 +02:00 committed by GitHub
parent 03d3245a39
commit f8551830c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 42 additions and 6 deletions

View File

@ -5775,6 +5775,14 @@ BattleScript_DisabledNoMore::
BattleScript_SelectingDisabledMoveInPalace::
printstring STRINGID_PKMNMOVEISDISABLED
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_EncoredMove::
printselectionstring STRINGID_PKMNGOTENCOREDMOVE
endselectionscript
BattleScript_EncoredMoveInPalace::
printselectionstring STRINGID_PKMNGOTENCOREDMOVE
BattleScript_SelectingUnusableMoveInPalace::
moveendto MOVEEND_NEXT_TARGET
end

View File

@ -72,6 +72,8 @@ extern const u8 BattleScript_RoarSuccessSwitch[];
extern const u8 BattleScript_RoarSuccessEndBattle[];
extern const u8 BattleScript_MistProtected[];
extern const u8 BattleScript_RageIsBuilding[];
extern const u8 BattleScript_EncoredMoveInPalace[];
extern const u8 BattleScript_EncoredMove[];
extern const u8 BattleScript_MoveUsedIsDisabled[];
extern const u8 BattleScript_SelectingDisabledMove[];
extern const u8 BattleScript_DisabledNoMore[];

View File

@ -233,7 +233,7 @@ void BattleScriptPushCursor(void);
void BattleScriptCall(const u8 *bsPtr);
void BattleScriptPop(void);
u32 TrySetCantSelectMoveBattleScript(u32 battler);
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
u32 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
bool32 AreAllMovesUnusable(u32 battler);
u8 GetImprisonedMovesCount(u32 battler, u16 move);
s32 GetDrainedBigRootHp(u32 battler, s32 hp);

View File

@ -129,6 +129,7 @@
#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly.
#define B_PURSUIT_TARGET GEN_LATEST // In Gen4+, Pursuit attacks a switching opponent even if they weren't targeting them. Before Gen4, Pursuit only attacks a switching opponent that it originally targeted.
#define B_SKIP_RECHARGE GEN_LATEST // In Gen1, recharging moves such as Hyper Beam skip the recharge if the target gets KO'd
#define B_ENCORE_TARGET GEN_LATEST // In Gen5+, encored moves are allowed to choose a target
// Ability settings
#define B_GALE_WINGS GEN_LATEST // In Gen7+ requires full HP to trigger.

View File

@ -138,6 +138,7 @@ enum StringID
STRINGID_PKMNMOVEISDISABLED,
STRINGID_PKMNMOVEDISABLEDNOMORE,
STRINGID_PKMNGOTENCORE,
STRINGID_PKMNGOTENCOREDMOVE,
STRINGID_PKMNENCOREENDED,
STRINGID_PKMNTOOKAIM,
STRINGID_PKMNSKETCHEDMOVE,

View File

@ -18,6 +18,7 @@ enum GenConfigTag
GEN_CONFIG_ATE_MULTIPLIER,
GEN_CONFIG_FELL_STINGER_STAT_RAISE,
GEN_CONFIG_DEFIANT_STICKY_WEB,
GEN_CONFIG_ENCORE_TARGET,
GEN_CONFIG_COUNT
};

View File

@ -18,9 +18,10 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] =
[GEN_CONFIG_ABILITY_WEATHER] = B_ABILITY_WEATHER,
[GEN_CONFIG_MOODY_STATS] = B_MOODY_ACC_EVASION,
[GEN_CONFIG_BATTLE_BOND] = B_BATTLE_BOND,
[GEN_CONFIG_FELL_STINGER_STAT_RAISE] = B_FELL_STINGER_STAT_RAISE,
[GEN_CONFIG_ATE_MULTIPLIER] = B_ATE_MULTIPLIER,
[GEN_CONFIG_FELL_STINGER_STAT_RAISE] = B_FELL_STINGER_STAT_RAISE,
[GEN_CONFIG_DEFIANT_STICKY_WEB] = B_DEFIANT_STICKY_WEB,
[GEN_CONFIG_ENCORE_TARGET] = B_ENCORE_TARGET,
};
#if TESTING

View File

@ -4237,7 +4237,7 @@ static void HandleTurnActionSelectionState(void)
gBattleStruct->moveTarget[battler] = gBattleResources->bufferB[battler][3];
return;
}
else if (gDisableStructs[battler].encoredMove != 0)
else if (GetGenConfig(GEN_CONFIG_ENCORE_TARGET) < GEN_5 && gDisableStructs[battler].encoredMove != MOVE_NONE)
{
gChosenMoveByBattler[battler] = gDisableStructs[battler].encoredMove;
gBattleStruct->chosenMovePositions[battler] = gDisableStructs[battler].encoredMovePos;

View File

@ -297,6 +297,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_PKMNMOVEISDISABLED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} is disabled!\p"),
[STRINGID_PKMNMOVEDISABLEDNOMORE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s move is no longer disabled!"),
[STRINGID_PKMNGOTENCORE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} must do an encore!"),
[STRINGID_PKMNGOTENCOREDMOVE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} can only use {B_CURRENT_MOVE}!\p"),
[STRINGID_PKMNENCOREENDED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} ended its encore!"),
[STRINGID_PKMNTOOKAIM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} took aim at {B_DEF_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNSKETCHEDMOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} sketched {B_BUFF1}!"),

View File

@ -1308,6 +1308,24 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
u16 *choicedMove = &gBattleStruct->choicedMove[battler];
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
if (GetGenConfig(GEN_CONFIG_ENCORE_TARGET) >= GEN_5
&& DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gDisableStructs[battler].encoredMove != move && gDisableStructs[battler].encoredMove != MOVE_NONE)
{
gBattleScripting.battler = battler;
gCurrentMove = gDisableStructs[battler].encoredMove;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
gPalaceSelectionBattleScripts[battler] = BattleScript_EncoredMoveInPalace;
gProtectStructs[battler].palaceUnableToUseMove = TRUE;
}
else
{
gSelectionBattleScripts[battler] = BattleScript_EncoredMove;
limitations++;
}
return limitations;
}
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(battler) != GIMMICK_Z_MOVE && gDisableStructs[battler].disabledMove == move && move != MOVE_NONE)
{
gBattleScripting.battler = battler;
@ -1544,7 +1562,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
return limitations;
}
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
u32 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
{
u32 move;
enum BattleMoveEffects moveEffect;
@ -1616,7 +1634,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
#define ALL_MOVES_MASK ((1 << MAX_MON_MOVES) - 1)
bool32 AreAllMovesUnusable(u32 battler)
{
u8 unusable = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
u32 unusable = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
if (unusable == ALL_MOVES_MASK) // All moves are unusable.
{

View File

@ -929,7 +929,6 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will stay in if Encore'd into
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if Encore'd into neutral move with good switchin 50% of the time")
{
KNOWN_FAILING; // AI still switches even if ShouldSwitch is set to immediately return FALSE, something external seems to be triggering this
PASSES_RANDOMLY(SHOULD_SWITCH_ENCORE_DAMAGE_PERCENTAGE, 100, RNG_AI_SWITCH_ENCORE);
GIVEN {
ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);

View File

@ -14,6 +14,7 @@ SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns: Encore used
PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 10; speedOpponent = 20; }
PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 20; speedOpponent = 10; }
GIVEN {
WITH_CONFIG(GEN_CONFIG_ENCORE_TARGET, GEN_3);
PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); }
} WHEN {
@ -41,6 +42,7 @@ SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player:
PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 20; speedOpponent = 10; }
PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 10; speedOpponent = 20; }
GIVEN {
WITH_CONFIG(GEN_CONFIG_ENCORE_TARGET, GEN_3);
PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); }
} WHEN {

View File

@ -32,6 +32,7 @@ SINGLE_BATTLE_TEST("Moves with the cantUseTwice flag strike again if fast encore
PARAMETRIZE { move = MOVE_GIGATON_HAMMER; }
PARAMETRIZE { move = MOVE_BLOOD_MOON; }
GIVEN {
WITH_CONFIG(GEN_CONFIG_ENCORE_TARGET, GEN_3);
ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);

View File

@ -1771,6 +1771,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your pa
DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves used after being Encore'd are prevented when sleep clause is active")
{
GIVEN {
WITH_CONFIG(GEN_CONFIG_ENCORE_TARGET, GEN_3);
FLAG_SET(B_FLAG_SLEEP_CLAUSE);
ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_NON_VOLATILE_STATUS);
ASSUME(GetMoveNonVolatileStatus(MOVE_SPORE) == MOVE_EFFECT_SLEEP);