Innards Out and Future Sight interaction

This commit is contained in:
wiz1989 2025-01-07 14:00:09 +01:00
parent 19d8f51f6d
commit 04da838d88
7 changed files with 134 additions and 4 deletions

View File

@ -310,6 +310,7 @@ struct WishFutureKnock
u8 wishPartyId[MAX_BATTLERS_COUNT];
u8 weatherDuration;
u8 knockedOffMons[NUM_BATTLE_SIDES]; // Each battler is represented by a bit.
u8 futureSightDmg[MAX_BATTLERS_COUNT];
};
struct AI_SavedBattleMon

View File

@ -137,6 +137,7 @@ bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect);
bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect);
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
bool32 IsHealingMove(u32 move);
bool32 IsForeSeenMove(u32 moveId);
bool32 HasHealingEffect(u32 battler);
bool32 IsTrappingMove(u32 move);
bool32 HasTrappingMoveEffect(u32 battler);

View File

@ -2188,6 +2188,14 @@ bool32 HasHealingEffect(u32 battlerId)
return FALSE;
}
bool32 IsForeSeenMove(u32 moveId)
{
if (moveId == MOVE_FUTURE_SIGHT || moveId == MOVE_DOOM_DESIRE)
return TRUE;
else
return FALSE;
}
bool32 IsTrappingMove(u32 move)
{
switch (gMovesInfo[move].effect)

View File

@ -2459,6 +2459,11 @@ static void Cmd_datahpupdate(void)
if (gSpecialStatuses[battler].shellBellDmg == 0 && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE))
gSpecialStatuses[battler].shellBellDmg = gHpDealt;
// Record damage for foreseen moves
if (gWishFutureKnock.futureSightDmg[battler] == 0
&& IsForeSeenMove(gWishFutureKnock.futureSightMove[battler]))
gWishFutureKnock.futureSightDmg[battler] = gHpDealt;
// Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are
// used in combination as general damage trackers for other purposes. specialDmg is additionally used
// to help determine if a fire move should defrost the target.
@ -13955,6 +13960,7 @@ static void Cmd_trysetfutureattack(void)
gWishFutureKnock.futureSightBattlerIndex[gBattlerTarget] = gBattlerAttacker;
gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] = gBattlerPartyIndexes[gBattlerAttacker];
gWishFutureKnock.futureSightCounter[gBattlerTarget] = 3;
gWishFutureKnock.futureSightDmg[gBattlerTarget] = 0;
if (gCurrentMove == MOVE_DOOM_DESIRE)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DOOM_DESIRE;

View File

@ -5803,10 +5803,26 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& !IsBattlerAlive(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker))
{
gBattleMoveDamage = gSpecialStatuses[gBattlerTarget].shellBellDmg;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AftermathDmg;
effect++;
//special Future Sight handling
if (IsForeSeenMove(gWishFutureKnock.futureSightMove[gBattlerTarget]))
{
//no Innards Out effect if Future Sight user is currently not on field
if (gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] == gBattlerPartyIndexes[gBattlerAttacker]
|| gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] == BATTLE_PARTNER(gBattlerPartyIndexes[gBattlerAttacker]))
{
gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gBattlerTarget];
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AftermathDmg;
effect++;
}
}
else
{
gBattleMoveDamage = gSpecialStatuses[gBattlerTarget].shellBellDmg;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AftermathDmg;
effect++;
}
}
break;
case ABILITY_EFFECT_SPORE:

View File

@ -65,3 +65,66 @@ SINGLE_BATTLE_TEST("Innards Out does not damage Magic Guard Pokemon")
NOT HP_BAR(opponent);
}
}
// IO damage for Future Sight must equal the actually lost HP of the Future Sight target
SINGLE_BATTLE_TEST("Innards Out uses correct damage amount for Future Sight")
{
GIVEN {
PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponent, MOVE_FUTURE_SIGHT); }
TURN { }
TURN { SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, opponent);
MESSAGE("Pyukumuku took the Future Sight attack!");
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_INNARDS_OUT);
HP_BAR(opponent, damage: 1);
}
}
// IO shouldn't trigger if future sight user is no longer on field
SINGLE_BATTLE_TEST("Innards Out doesn't trigger if Future Sight user is not on field")
{
GIVEN {
PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponent, MOVE_FUTURE_SIGHT); }
TURN { SWITCH(opponent, 1); }
TURN { SEND_OUT(player, 1); } //SEND_OUT(opponent, 0); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, opponent);
MESSAGE("Pyukumuku took the Future Sight attack!");
HP_BAR(player);
NONE_OF {
ABILITY_POPUP(player, ABILITY_INNARDS_OUT);
HP_BAR(opponent);
}
}
}
//IO should trigger if future sight user returns on the field
SINGLE_BATTLE_TEST("Innards Out triggers if Future Sight user is back on the field")
{
GIVEN {
PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(opponent, MOVE_FUTURE_SIGHT); }
TURN { SWITCH(opponent, 1); }
TURN { SWITCH(opponent, 0); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, opponent);
MESSAGE("Pyukumuku took the Future Sight attack!");
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_INNARDS_OUT);
HP_BAR(opponent);
}
}

View File

@ -0,0 +1,35 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Shell Bell restores 1/8 HP of damage dealt")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Level(16); Item(ITEM_SHELL_BELL); HP(10); }
OPPONENT(SPECIES_WOBBUFFET) { Level(16); };
} WHEN {
TURN { MOVE(player, MOVE_SEISMIC_TOSS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SEISMIC_TOSS, player);
HP_BAR(opponent);
HP_BAR(player, damage: -2);
}
}
SINGLE_BATTLE_TEST("Shell Bell doesn't restore HP for damage dealt by a foreseen move")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Level(16); Item(ITEM_SHELL_BELL); HP(10); }
OPPONENT(SPECIES_WOBBUFFET) { Level(16); };
} WHEN {
TURN { MOVE(player, MOVE_FUTURE_SIGHT); }
TURN { }
TURN { }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, player);
MESSAGE("The opposing Wobbuffet took the Future Sight attack!");
HP_BAR(opponent);
NONE_OF {
HP_BAR(player);
}
}
}