Misc battle engine changes (#8931)

This commit is contained in:
Alex 2026-01-16 18:55:22 +01:00 committed by GitHub
parent 31d3e5f022
commit de7aaf854c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 78 additions and 49 deletions

View File

@ -2328,11 +2328,6 @@
callnative BS_TryResetNegativeStatStages
.endm
.macro jumpiflastuseditemberry jumpInstr:req
callnative BS_JumpIfLastUsedItemBerry
.4byte \jumpInstr
.endm
.macro savebattleritem
callnative BS_SaveBattlerItem
.endm

View File

@ -576,11 +576,10 @@ BattleScript_EffectFling::
waitmessage B_WAIT_TIME_MED
resultmessage
waitmessage B_WAIT_TIME_MED
jumpiflastuseditemberry BattleScript_EffectFlingConsumeBerry
tryflingholdeffect
goto BattleScript_FlingEnd
BattleScript_EffectFlingConsumeBerry:
BattleScript_EffectFlingConsumeBerry::
savebattleritem
battleritemtolastuseditem
setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries
@ -7106,7 +7105,6 @@ BattleScript_BerryCureStatusRet::
BattleScript_GemActivates::
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
waitanimation
setlastuseditem BS_ATTACKER
printstring STRINGID_GEMACTIVATES
waitmessage B_WAIT_TIME_LONG
removeitem BS_ATTACKER
@ -7115,7 +7113,6 @@ BattleScript_GemActivates::
BattleScript_BerryReduceDmg::
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT
waitanimation
setlastuseditem BS_SCRIPTING
printstring STRINGID_BERRYDMGREDUCES
waitmessage B_WAIT_TIME_LONG
removeitem BS_SCRIPTING

View File

@ -14,6 +14,7 @@ extern const u8 BattleScript_MoveMissedPause[];
extern const u8 BattleScript_MoveMissed[];
extern const u8 BattleScript_FlingFailConsumeItem[];
extern const u8 BattleScript_FlingBlockedByShieldDust[];
extern const u8 BattleScript_EffectFlingConsumeBerry[];
extern const u8 BattleScript_FailedFromAtkCanceler[];
extern const u8 BattleScript_ButItFailed[];
extern const u8 BattleScript_StatUp[];

View File

@ -39,6 +39,7 @@ enum MoveEndState
MOVEEND_ITEM_EFFECTS_ATTACKER_2,
MOVEEND_ABILITY_EFFECT_FOES_FAINTED, // Moxie-like abilities / Battle Bond / Magician
MOVEEND_SHEER_FORCE, // If move is Sheer Force affected, skip to Hit Escape + One
MOVEEND_SHELL_TRAP,
MOVEEND_COLOR_CHANGE, // Color Change / Berserk / Anger Shell
MOVEEND_KEE_MARANGA_HP_THRESHOLD_ITEM_TARGET,
MOVEEND_CARD_BUTTON, // Red Card / Eject Button

View File

@ -563,23 +563,6 @@ static enum MoveEndResult MoveEnd_UpdateLastMoves(void)
|| gBattleStruct->unableToUseMove)
gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2;
// Set ShellTrap to activate after the attacker's turn if target was hit by a physical move.
if (GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP
&& IsBattleMovePhysical(gCurrentMove)
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gBattlerTarget != gBattlerAttacker
&& !IsBattlerAlly(gBattlerTarget, gBattlerAttacker)
&& gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker
&& !IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker)))
{
gProtectStructs[gBattlerTarget].shellTrap = TRUE;
// Change move order in double battles, so the hit mon with shell trap moves immediately after being hit.
if (IsDoubleBattle())
{
ChangeOrderTargetAfterAttacker();
}
}
// After swapattackerwithtarget is used for snatch the correct battlers have to be restored so data is stored correctly
if (gBattleStruct->snatchedMoveIsUsed)
{
@ -1132,6 +1115,29 @@ static enum MoveEndResult MoveEnd_SheerForce(void)
return MOVEEND_STEP_CONTINUE;
}
static enum MoveEndResult MoveEnd_ShellTrap(void)
{
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
if (battlerDef == gBattlerAttacker || IsBattlerAlly(battlerDef, gBattlerAttacker))
continue;
// Set ShellTrap to activate after the attacker's turn if target was hit by a physical move.
if (GetMoveEffect(gChosenMoveByBattler[battlerDef]) == EFFECT_SHELL_TRAP
&& IsBattleMovePhysical(gCurrentMove)
&& IsBattlerTurnDamaged(battlerDef)
&& gProtectStructs[battlerDef].physicalBattlerId == gBattlerAttacker)
{
gProtectStructs[battlerDef].shellTrap = TRUE;
if (IsDoubleBattle()) // Change move order in double battles, so the hit mon with shell trap moves immediately after being hit.
ChangeOrderTargetAfterAttacker(); // In what order should 2 targets move that will activate a trap?
}
}
gBattleScripting.moveendState++;
return MOVEEND_STEP_CONTINUE;
}
static enum MoveEndResult MoveEnd_ColorChange(void)
{
while (gBattleStruct->eventState.moveEndBattler < gBattlersCount)
@ -1762,6 +1768,7 @@ static enum MoveEndResult (*const sMoveEndHandlers[])(void) =
[MOVEEND_ITEM_EFFECTS_ATTACKER_2] = MoveEnd_ItemEffectsAttacker2,
[MOVEEND_ABILITY_EFFECT_FOES_FAINTED] = MoveEnd_AbilityEffectFoesFainted,
[MOVEEND_SHEER_FORCE] = MoveEnd_SheerForce,
[MOVEEND_SHELL_TRAP] = MoveEnd_ShellTrap,
[MOVEEND_COLOR_CHANGE] = MoveEnd_ColorChange,
[MOVEEND_KEE_MARANGA_HP_THRESHOLD_ITEM_TARGET] = MoveEnd_KeeMarangaHpThresholdItemTarget,
[MOVEEND_CARD_BUTTON] = MoveEnd_CardButton,

View File

@ -9553,15 +9553,6 @@ static void Cmd_magnitudedamagecalculation(void)
}
PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 2, magnitude)
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
if (gBattlerTarget == gBattlerAttacker)
continue;
if (!(gAbsentBattlerFlags & (1u << gBattlerTarget))) // A valid target was found.
break;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}
@ -13628,7 +13619,12 @@ void BS_TryFlingHoldEffect(void)
{
NATIVE_ARGS();
enum HoldEffect holdEffect = GetItemHoldEffect(gBattleStruct->flingItem);
gBattleStruct->flingItem = ITEM_NONE;
if (GetItemPocket(gBattleStruct->flingItem) == POCKET_BERRIES)
{
gBattlescriptCurrInstr = BattleScript_EffectFlingConsumeBerry;
return;
}
if (IsMoveEffectBlockedByTarget(GetBattlerAbility(gBattlerTarget)))
{
@ -13648,7 +13644,7 @@ void BS_TryFlingHoldEffect(void)
SetMoveEffect(gBattlerAttacker, gBattlerTarget, MOVE_EFFECT_PARALYSIS, cmd->nextInstr, NO_FLAGS);
break;
case HOLD_EFFECT_TYPE_POWER:
if (GetItemSecondaryId(gLastUsedItem) != TYPE_POISON)
if (GetItemSecondaryId(gBattleStruct->flingItem) != TYPE_POISON)
gBattlescriptCurrInstr = cmd->nextInstr;
else
SetMoveEffect(gBattlerAttacker, gBattlerTarget, MOVE_EFFECT_POISON, cmd->nextInstr, NO_FLAGS);
@ -15245,15 +15241,6 @@ void BS_TryResetNegativeStatStages(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_JumpIfLastUsedItemBerry(void)
{
NATIVE_ARGS(const u8 *jumpInstr);
if (GetItemPocket(gLastUsedItem) == POCKET_BERRIES)
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_SaveBattlerItem(void)
{
NATIVE_ARGS();

View File

@ -7227,7 +7227,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] =
.type = TYPE_NORMAL,
.accuracy = 0,
.pp = 20,
.target = TARGET_DEPENDS,
.target = B_UPDATED_MOVE_FLAGS >= GEN_6 ? TARGET_SELECTED : TARGET_DEPENDS,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.metronomeBanned = B_UPDATED_MOVE_FLAGS >= GEN_5,

View File

@ -8,10 +8,11 @@ SINGLE_BATTLE_TEST("Nature power plays a move correctly in any background")
{
u32 environment = 0;
enum Move move = MOVE_TRI_ATTACK;
for (u32 j = 0; j < BATTLE_ENVIRONMENT_COUNT; j++)
{
for (u32 j = 0; j < BATTLE_ENVIRONMENT_COUNT; j++) {
PARAMETRIZE { environment = i; }
}
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@ -25,3 +26,19 @@ SINGLE_BATTLE_TEST("Nature power plays a move correctly in any background")
ANIMATION(ANIM_TYPE_MOVE, move, player);
}
}
#if B_UPDATED_MOVE_FLAGS >= GEN_6
DOUBLE_BATTLE_TEST("Nature Power can target ally (Gen6+)")
{
GIVEN {
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(playerLeft, MOVE_NATURE_POWER, target: playerRight); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, playerLeft);
}
}
#endif

View File

@ -279,3 +279,26 @@ DOUBLE_BATTLE_TEST("Shell Trap does not trigger when hit into Substitute")
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
}
}
DOUBLE_BATTLE_TEST("Shell Trap activates on both opposing Targets")
{
GIVEN {
ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {
MOVE(playerLeft, MOVE_SHELL_TRAP);
MOVE(playerRight, MOVE_SHELL_TRAP);
MOVE(opponentLeft, MOVE_EARTHQUAKE);
}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, opponentLeft);
// Order might be incorrect compared to vanilla
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHELL_TRAP, playerRight);
}
}

View File

@ -85,3 +85,4 @@ SINGLE_BATTLE_TEST("Tar Shot does affect Pokemon that Terastallized after Tar Sh
EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]);
}
}