Merge branch 'master' of https://github.com/rh-hideout/pokeemerald-expansion into rh-hideout-master

This commit is contained in:
RoamerX 2025-04-15 22:17:30 +08:00
commit 184ec657ac
17 changed files with 223 additions and 82 deletions

View File

@ -3642,7 +3642,7 @@ gBattleAnimMove_MagmaStorm::
call FireSpinEffect
restorebg
waitbgfadeout
setarg 7, 0xFFFF
setarg 7, 0xFFF
waitbgfadein
clearmonbg ANIM_DEF_PARTNER
blendoff
@ -28313,7 +28313,7 @@ Status_MagmaStorm:
call FireSpinEffect
restorebg
waitbgfadeout
setarg 7, 0xFFFF
setarg 7, 0xFFF
waitbgfadein
stopsound
clearmonbg ANIM_DEF_PARTNER

View File

@ -7030,9 +7030,9 @@ BattleScript_BattlerFormChangeWithStringEnd3::
BattleScript_IllusionOff::
spriteignore0hp TRUE
playanimation BS_TARGET, B_ANIM_ILLUSION_OFF
playanimation BS_SCRIPTING, B_ANIM_ILLUSION_OFF
waitanimation
updatenick BS_TARGET
updatenick BS_SCRIPTING
waitstate
spriteignore0hp FALSE
printstring STRINGID_ILLUSIONWOREOFF
@ -9994,9 +9994,12 @@ BattleScript_DynamaxEnds::
BattleScript_DynamaxEnds_Ret::
flushtextbox
spriteignore0hp TRUE
updatedynamax
playanimation BS_SCRIPTING, B_ANIM_FORM_CHANGE
waitanimation
spriteignore0hp FALSE
pause B_WAIT_TIME_SHORT
return
BattleScript_MoveBlockedByDynamax::

View File

@ -834,7 +834,6 @@ struct BattleStruct
u8 usedMicleBerry;
struct MessageStatus slideMessageStatus;
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];
u8 embodyAspectBoost[NUM_BATTLE_SIDES];
u16 savedMove; // backup current move for mid-turn switching, e.g. Red Card
u16 opponentMonCanTera:6;
u16 opponentMonCanDynamax:6;

View File

@ -19,7 +19,7 @@
#define DEXNAV_CHAIN_MAX 100 // maximum chain value
// hidden pokemon options - an approximation of values to due to lack of available data
// hidden pokemon options - an approximation of values due to lack of available data
#define HIDDEN_MON_STEP_COUNT 100 // Look for hidden pokemon every x steps
#define HIDDEN_MON_SEARCH_RATE 25 // x% chance of finding hidden pokemon every x steps
#define HIDDEN_MON_PROBABILTY 15 // x% chance of finding hidden mon compared to regular encounter data

View File

@ -1,19 +1,6 @@
#ifndef GUARD_CONSTANTS_BATTLE_AI_H
#define GUARD_CONSTANTS_BATTLE_AI_H
// battlers
#define AI_TARGET 0
#define AI_USER 1
#define AI_TARGET_PARTNER 2
#define AI_USER_PARTNER 3
// get_type command
#define AI_TYPE1_TARGET 0
#define AI_TYPE1_USER 1
#define AI_TYPE2_TARGET 2
#define AI_TYPE2_USER 3
#define AI_TYPE_MOVE 4
// AI Flags. Most run specific functions to update score, new flags are used for internal logic in other scripts
// See docs/ai_flags.md for more details.
#define AI_FLAG_CHECK_BAD_MOVE (1 << 0) // AI will avoid using moves that are likely to fail or be ineffective in the current situation.

View File

@ -283,7 +283,7 @@ enum EvolutionMethods {
EVO_LEVEL_NATURE_AMPED, // Pokémon reaches the specified level, it has a Hardy, Brave, Adamant, Naughty, Docile, Impish, Lax, Hasty, Jolly, Naive, Rash, Sassy, or Quirky nature.
EVO_LEVEL_NATURE_LOW_KEY, // Pokémon reaches the specified level, it has a Lonely, Bold, Relaxed, Timid, Serious, Modest, Mild, Quiet, Bashful, Calm, Gentle, or Careful nature.
EVO_CRITICAL_HITS, // Pokémon performs specified number of critical hits in one battle
EVO_SCRIPT_TRIGGER_DMG, // Pokémon has specified HP below max, then player interacts trigger
EVO_SCRIPT_TRIGGER_DMG, // Pokémon has specified HP below max, then player interacts with script calling "tryspecialevo EVO_SCRIPT_TRIGGER_DMG"
EVO_DARK_SCROLL, // interacts with Scroll of Darkness
EVO_WATER_SCROLL, // interacts with Scroll of Waters
EVO_ITEM_NIGHT, // specified item is used on Pokémon, is night

View File

@ -696,11 +696,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_GEMACTIVATES] = COMPOUND_STRING("The {B_LAST_ITEM} strengthened {B_ATK_NAME_WITH_PREFIX2}的power!"),
[STRINGID_BERRYDMGREDUCES] = COMPOUND_STRING("The {B_LAST_ITEM} weakened the damage to {B_SCR_NAME_WITH_PREFIX2}!"),
[STRINGID_AIRBALLOONFLOAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} floats in the air with its Air Balloon!"),
[STRINGID_AIRBALLOONPOP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}Air Balloon popped!"),
[STRINGID_INCINERATEBURN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}{B_LAST_ITEM} was burnt up!"),
[STRINGID_BUGBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole and ate its target{B_LAST_ITEM}!"),
[STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}的illusion wore off!"),
[STRINGID_ATTACKERCUREDTARGETSTATUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured {B_DEF_NAME_WITH_PREFIX2}problem!"),
[STRINGID_AIRBALLOONPOP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s Air Balloon popped!"),
[STRINGID_INCINERATEBURN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM} was burnt up!"),
[STRINGID_BUGBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole and ate its target's {B_LAST_ITEM}!"),
[STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s illusion wore off!"),
[STRINGID_ATTACKERCUREDTARGETSTATUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured {B_DEF_NAME_WITH_PREFIX2}'s problem!"),
[STRINGID_ATTACKERLOSTFIRETYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} burned itself out!"),
[STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}的{B_LAST_ABILITY} cured {B_SCR_NAME_WITH_PREFIX2}的problem!"),
[STRINGID_SCRIPTINGABILITYSTATRAISE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}的{B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"),

View File

@ -10178,6 +10178,7 @@ static void Cmd_various(void)
VARIOUS_ARGS();
if (GetIllusionMonPtr(battler) != NULL)
{
gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff;

View File

@ -4764,8 +4764,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_IMPOSTER:
{
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
if (IsDoubleBattle())
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
if (IsDoubleBattle())
diagonalBattler = BATTLE_PARTNER(diagonalBattler);
if (IsBattlerAlive(diagonalBattler)
&& !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
@ -5303,8 +5303,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_EMBODY_ASPECT_HEARTHFLAME_MASK:
case ABILITY_EMBODY_ASPECT_WELLSPRING_MASK:
case ABILITY_EMBODY_ASPECT_CORNERSTONE_MASK:
if (!gSpecialStatuses[battler].switchInAbilityDone
&& !(gBattleStruct->embodyAspectBoost[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler])))
if (!gSpecialStatuses[battler].switchInAbilityDone)
{
u32 stat;
@ -5323,7 +5322,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
gBattleScripting.savedBattler = gBattlerAttacker;
gBattlerAttacker = battler;
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
gBattleStruct->embodyAspectBoost[GetBattlerSide(battler)] |= 1u << gBattlerPartyIndexes[battler];
SET_STATCHANGER(stat, 1, FALSE);
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
effect++;
@ -6015,6 +6013,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_ILLUSION:
if (gBattleStruct->illusion[gBattlerTarget].on && !gBattleStruct->illusion[gBattlerTarget].broken && IsBattlerTurnDamaged(gBattlerTarget))
{
gBattleScripting.battler = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff;
effect++;
@ -11271,19 +11270,12 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battler)
{
struct Pokemon *party, *partnerMon;
s32 i, id;
u8 side, partyCount;
gBattleStruct->illusion[battler].set = 1;
if (GetMonAbility(mon) != ABILITY_ILLUSION)
return FALSE;
party = GetBattlerParty(battler);
side = GetBattlerSide(battler);
partyCount = side == B_SIDE_PLAYER ? gPlayerPartyCount : gEnemyPartyCount;
// If this pokemon is last in the party, ignore Illusion.
if (&party[partyCount - 1] == mon)
return FALSE;
if (IsBattlerAlive(BATTLE_PARTNER(battler)))
partnerMon = &party[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]];
@ -11296,15 +11288,21 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battler)
id = i;
if (GetMonData(&party[id], MON_DATA_SANITY_HAS_SPECIES)
&& GetMonData(&party[id], MON_DATA_HP)
&& !GetMonData(&party[id], MON_DATA_IS_EGG)
&& &party[id] != mon
&& &party[id] != partnerMon)
&& !GetMonData(&party[id], MON_DATA_IS_EGG))
{
gBattleStruct->illusion[battler].on = 1;
gBattleStruct->illusion[battler].broken = 0;
gBattleStruct->illusion[battler].partyId = id;
gBattleStruct->illusion[battler].mon = &party[id];
return TRUE;
if (&party[id] != mon && &party[id] != partnerMon)
{
gBattleStruct->illusion[battler].on = 1;
gBattleStruct->illusion[battler].broken = 0;
gBattleStruct->illusion[battler].partyId = id;
gBattleStruct->illusion[battler].mon = &party[id];
return TRUE;
}
else if (&party[id] == mon)
{
// If this pokemon is last in the party, ignore Illusion.
return FALSE;
}
}
}

View File

@ -84,17 +84,16 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
u32 GetCurrentEVCap(void)
{
static const u16 sEvCapFlagMap[][2] = {
// Define EV caps for each milestone
{FLAG_BADGE01_GET, 30},
{FLAG_BADGE02_GET, 90},
{FLAG_BADGE03_GET, 150},
{FLAG_BADGE04_GET, 210},
{FLAG_BADGE05_GET, 270},
{FLAG_BADGE06_GET, 330},
{FLAG_BADGE07_GET, 390},
{FLAG_BADGE08_GET, 450},
{FLAG_BADGE01_GET, MAX_TOTAL_EVS * 1 / 17},
{FLAG_BADGE02_GET, MAX_TOTAL_EVS * 3 / 17},
{FLAG_BADGE03_GET, MAX_TOTAL_EVS * 5 / 17},
{FLAG_BADGE04_GET, MAX_TOTAL_EVS * 7 / 17},
{FLAG_BADGE05_GET, MAX_TOTAL_EVS * 9 / 17},
{FLAG_BADGE06_GET, MAX_TOTAL_EVS * 11 / 17},
{FLAG_BADGE07_GET, MAX_TOTAL_EVS * 13 / 17},
{FLAG_BADGE08_GET, MAX_TOTAL_EVS * 15 / 17},
{FLAG_IS_CHAMPION, MAX_TOTAL_EVS},
};

View File

@ -99,7 +99,7 @@ static const u16 sMiscIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mis
static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal");
static const u16 sTeraIndicatorPal[] = INCBIN_U16("graphics/battle_interface/tera_indicator.gbapal");
static const u8 *sTeraIndicatorDataPtrs[] =
static const u8 *const sTeraIndicatorDataPtrs[] =
{
sNormalIndicatorGfx,
sNormalIndicatorGfx,

View File

@ -57,26 +57,3 @@ SINGLE_BATTLE_TEST("Embody Aspect activates when it's no longer effected by Neut
MESSAGE("The opposing Ogerpon's Embody Aspect raised its Speed!");
}
}
SINGLE_BATTLE_TEST("Embody Aspect raises Speed only once per battle")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_OGERPON_TEAL_TERA) { Ability(ABILITY_EMBODY_ASPECT_TEAL_MASK); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { SWITCH(opponent, 1); }
TURN { SWITCH(opponent, 0); }
} SCENE {
ABILITY_POPUP(opponent, ABILITY_EMBODY_ASPECT_TEAL_MASK);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("The opposing Ogerpon's Embody Aspect raised its Speed!");
NONE_OF {
ABILITY_POPUP(opponent, ABILITY_EMBODY_ASPECT_TEAL_MASK);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("The opposing Ogerpon's Embody Aspect raised its Speed!");
}
} THEN {
EXPECT_EQ(opponent->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
}
}

View File

@ -22,3 +22,50 @@ SINGLE_BATTLE_TEST("Illusion can only imitate Normal Form terapagos")
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); }
}
}
SINGLE_BATTLE_TEST("Illusion breaks if the target faints")
{
GIVEN {
PLAYER(SPECIES_ZOROARK) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ILLUSION_OFF, player);
MESSAGE("Zoroark's illusion wore off!");
}
}
SINGLE_BATTLE_TEST("Illusion breaks if the attacker faints")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_FINAL_GAMBIT) == EFFECT_FINAL_GAMBIT);
PLAYER(SPECIES_ZOROARK) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_FINAL_GAMBIT); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FINAL_GAMBIT, player);
HP_BAR(player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ILLUSION_OFF, player);
MESSAGE("Zoroark's illusion wore off!");
}
}
SINGLE_BATTLE_TEST("Illusion cannot imitate if the user is on the last slot")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZOROARK);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { SWITCH(player, 1); }
} THEN {
EXPECT_EQ(player->species, SPECIES_ZOROARK);
EXPECT_EQ(gBattleStruct->illusion[0].on, FALSE); // Battler is Zoroark and not Illusioned
}
}

View File

@ -860,3 +860,34 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI considers Focus Sash when det
TURN { MOVE(player, MOVE_AIR_SLASH); EXPECT_MOVE(opponent, MOVE_FLAMETHROWER); }
}
}
AI_SINGLE_BATTLE_TEST("AI sees popped Air Balloon")
{
GIVEN {
ASSUME(ItemId_GetHoldEffect(ITEM_AIR_BALLOON) == HOLD_EFFECT_AIR_BALLOON);
ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_TORCHIC) { Item(ITEM_AIR_BALLOON); Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_GEODUDE) { Moves(MOVE_TACKLE, MOVE_EARTHQUAKE); }
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_TACKLE); }
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_EARTHQUAKE); }
}
}
AI_SINGLE_BATTLE_TEST("AI sees popped Air Balloon after Air Balloon mon switches out and back in")
{
GIVEN {
ASSUME(ItemId_GetHoldEffect(ITEM_AIR_BALLOON) == HOLD_EFFECT_AIR_BALLOON);
ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_TORCHIC) { Item(ITEM_AIR_BALLOON); Moves(MOVE_TACKLE); }
PLAYER(SPECIES_TORCHIC) { Item(ITEM_AIR_BALLOON); Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_GEODUDE) { Moves(MOVE_TACKLE, MOVE_EARTHQUAKE); }
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_TACKLE); }
TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_EARTHQUAKE); }
TURN { SWITCH(player, 0); EXPECT_MOVE(opponent, MOVE_TACKLE); }
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_EARTHQUAKE); SEND_OUT(player, 1); }
}
}

View File

@ -68,6 +68,29 @@ SINGLE_BATTLE_TEST("Dynamax: Dynamax Level increases HP and max HP multipliers b
}
}
SINGLE_BATTLE_TEST("Dynamax: Dynamax expires when fainted")
{
u32 dynamax;
PARAMETRIZE { dynamax = GIMMICK_NONE; }
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_TACKLE); }
} SCENE {
if (dynamax)
MESSAGE("Wobbuffet used Max Strike!");
else
MESSAGE("Wobbuffet used Tackle!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player);
if (dynamax) // Expect to have visual reversion when fainting.
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Wobbuffet fainted!");
}
}
SINGLE_BATTLE_TEST("Dynamax: Dynamax expires after three turns", u16 hp)
{
u32 dynamax;

View File

@ -0,0 +1,80 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_BIG_ROOT].holdEffect == HOLD_EFFECT_BIG_ROOT);
}
SINGLE_BATTLE_TEST("Big Root increases healing from absorbing moves", s16 damage, s16 heal)
{
u32 item;
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BIG_ROOT; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(200); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_ABSORB); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
HP_BAR(player, captureDamage: &results[i].heal);
} FINALLY {
EXPECT_EQ(results[0].damage, results[1].damage); // Damage is unaffected
EXPECT_MUL_EQ(results[1].heal, Q_4_12(5234 / 4096), results[0].heal);
}
}
SINGLE_BATTLE_TEST("Big Root increases the damage restored from Leech Seed, Ingrain and Aqua Ring", s16 heal, s16 damage)
{
KNOWN_FAILING;
u32 item;
u32 move;
PARAMETRIZE { item = ITEM_NONE; move = MOVE_LEECH_SEED; }
PARAMETRIZE { item = ITEM_BIG_ROOT; move = MOVE_LEECH_SEED; }
PARAMETRIZE { item = ITEM_NONE; move = MOVE_INGRAIN; }
PARAMETRIZE { item = ITEM_BIG_ROOT; move = MOVE_INGRAIN; }
PARAMETRIZE { item = ITEM_NONE; move = MOVE_AQUA_RING; }
PARAMETRIZE { item = ITEM_BIG_ROOT; move = MOVE_AQUA_RING; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(200); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
if (move == MOVE_LEECH_SEED)
HP_BAR(opponent, captureDamage: &results[i].damage);
HP_BAR(player, captureDamage: &results[i].heal);
} FINALLY {
EXPECT_EQ(results[0].damage, results[1].damage); // Damage is unaffected
EXPECT_MUL_EQ(results[1].heal, Q_4_12(5234 / 4096), results[0].heal);
EXPECT_MUL_EQ(results[3].heal, Q_4_12(5234 / 4096), results[2].heal);
EXPECT_MUL_EQ(results[5].heal, Q_4_12(5234 / 4096), results[4].heal);
}
}
SINGLE_BATTLE_TEST("Big Root increases damage from absorbing Liquid Ooze", s16 damage)
{
u32 item;
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BIG_ROOT; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(200); Item(item); }
OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
} WHEN {
TURN { MOVE(player, MOVE_ABSORB); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
HP_BAR(player, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[1].damage, Q_4_12(5234 / 4096), results[0].damage);
}
}

View File

@ -277,11 +277,8 @@ DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is be
}
}
// Test passes in isolation but fails on CI
/*
DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
{
KNOWN_FAILING; // Test passes in isolation but fails on CI
GIVEN {
ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH);
PLAYER(SPECIES_HOOPA);
@ -295,7 +292,6 @@ DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
EXPECT(&gPlayerParty[2] == gBattleStruct->illusion[0].mon);
}
}
*/
// Triple Battles required to test
//TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle");