Add SUB_HIT check to tests (#8413)
Co-authored-by: Hedara <hedara90@gmail.com>
This commit is contained in:
parent
3feeebce9b
commit
ec1a283b1b
@ -464,6 +464,20 @@ If the expected status icon is parametrized the corresponding `STATUS1` constant
|
|||||||
STATUS_ICON(player, status1);
|
STATUS_ICON(player, status1);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `SUB_HIT`
|
||||||
|
`SUB_HIT(battler, captureDamage: | subBreak:)`
|
||||||
|
Causes the test to fail the test to fail if a Substitute for the specified battler doesn't take damage.
|
||||||
|
If `captureDamage` is used, the damage the substitute takes is written to the supplied pointer.
|
||||||
|
```
|
||||||
|
u16 damage;
|
||||||
|
...
|
||||||
|
SUB_HIT(player, captureDamage: &damage);
|
||||||
|
```
|
||||||
|
If `subBreak` is set to `TRUE`, the test will fail unless the substitute breaks. And if set to `FALSE`, the test will fail unless the substitute survives.
|
||||||
|
```
|
||||||
|
SUB_HIT(player, subBreak: TRUE);
|
||||||
|
```
|
||||||
|
|
||||||
### `NOT`
|
### `NOT`
|
||||||
`NOT sceneCommand`
|
`NOT sceneCommand`
|
||||||
Causes the test to fail if the `SCENE` command succeeds before the following command succeeds.
|
Causes the test to fail if the `SCENE` command succeeds before the following command succeeds.
|
||||||
|
|||||||
@ -606,6 +606,7 @@ enum
|
|||||||
QUEUED_ABILITY_POPUP_EVENT,
|
QUEUED_ABILITY_POPUP_EVENT,
|
||||||
QUEUED_ANIMATION_EVENT,
|
QUEUED_ANIMATION_EVENT,
|
||||||
QUEUED_HP_EVENT,
|
QUEUED_HP_EVENT,
|
||||||
|
QUEUED_SUB_HIT_EVENT,
|
||||||
QUEUED_EXP_EVENT,
|
QUEUED_EXP_EVENT,
|
||||||
QUEUED_MESSAGE_EVENT,
|
QUEUED_MESSAGE_EVENT,
|
||||||
QUEUED_STATUS_EVENT,
|
QUEUED_STATUS_EVENT,
|
||||||
@ -635,6 +636,14 @@ struct QueuedHPEvent
|
|||||||
u32 address:28;
|
u32 address:28;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QueuedSubHitEvent
|
||||||
|
{
|
||||||
|
u32 battlerId:3;
|
||||||
|
u32 checkBreak:1;
|
||||||
|
u32 breakSub:1;
|
||||||
|
u32 address:27;
|
||||||
|
};
|
||||||
|
|
||||||
struct QueuedExpEvent
|
struct QueuedExpEvent
|
||||||
{
|
{
|
||||||
u32 battlerId:3;
|
u32 battlerId:3;
|
||||||
@ -664,6 +673,7 @@ struct QueuedEvent
|
|||||||
struct QueuedAbilityEvent ability;
|
struct QueuedAbilityEvent ability;
|
||||||
struct QueuedAnimationEvent animation;
|
struct QueuedAnimationEvent animation;
|
||||||
struct QueuedHPEvent hp;
|
struct QueuedHPEvent hp;
|
||||||
|
struct QueuedSubHitEvent subHit;
|
||||||
struct QueuedExpEvent exp;
|
struct QueuedExpEvent exp;
|
||||||
struct QueuedMessageEvent message;
|
struct QueuedMessageEvent message;
|
||||||
struct QueuedStatusEvent status;
|
struct QueuedStatusEvent status;
|
||||||
@ -1173,6 +1183,7 @@ void SendOut(u32 sourceLine, struct BattlePokemon *, u32 partyIndex);
|
|||||||
#define ABILITY_POPUP(battler, ...) QueueAbility(__LINE__, battler, (struct AbilityEventContext) { __VA_ARGS__ })
|
#define ABILITY_POPUP(battler, ...) QueueAbility(__LINE__, battler, (struct AbilityEventContext) { __VA_ARGS__ })
|
||||||
#define ANIMATION(type, id, ...) QueueAnimation(__LINE__, type, id, (struct AnimationEventContext) { __VA_ARGS__ })
|
#define ANIMATION(type, id, ...) QueueAnimation(__LINE__, type, id, (struct AnimationEventContext) { __VA_ARGS__ })
|
||||||
#define HP_BAR(battler, ...) QueueHP(__LINE__, battler, (struct HPEventContext) { R_APPEND_TRUE(__VA_ARGS__) })
|
#define HP_BAR(battler, ...) QueueHP(__LINE__, battler, (struct HPEventContext) { R_APPEND_TRUE(__VA_ARGS__) })
|
||||||
|
#define SUB_HIT(battler, ...) QueueSubHit(__LINE__, battler, (struct SubHitEventContext) { R_APPEND_TRUE(__VA_ARGS__) })
|
||||||
#define EXPERIENCE_BAR(battler, ...) QueueExp(__LINE__, battler, (struct ExpEventContext) { R_APPEND_TRUE(__VA_ARGS__) })
|
#define EXPERIENCE_BAR(battler, ...) QueueExp(__LINE__, battler, (struct ExpEventContext) { R_APPEND_TRUE(__VA_ARGS__) })
|
||||||
// Static const is needed to make the modern compiler put the pattern variable in the .rodata section, instead of putting it on stack(which can break the game).
|
// Static const is needed to make the modern compiler put the pattern variable in the .rodata section, instead of putting it on stack(which can break the game).
|
||||||
#define MESSAGE(pattern) do {static const u8 msg[] = _(pattern); QueueMessage(__LINE__, msg);} while (0)
|
#define MESSAGE(pattern) do {static const u8 msg[] = _(pattern); QueueMessage(__LINE__, msg);} while (0)
|
||||||
@ -1225,6 +1236,15 @@ struct HPEventContext
|
|||||||
bool8 explicitCaptureDamage;
|
bool8 explicitCaptureDamage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SubHitEventContext
|
||||||
|
{
|
||||||
|
u8 _;
|
||||||
|
bool8 subBreak;
|
||||||
|
bool8 explicitSubBreak;
|
||||||
|
u16 *captureDamage;
|
||||||
|
bool8 explicitCaptureDamage;
|
||||||
|
};
|
||||||
|
|
||||||
struct ExpEventContext
|
struct ExpEventContext
|
||||||
{
|
{
|
||||||
u8 _;
|
u8 _;
|
||||||
@ -1253,6 +1273,7 @@ void CloseQueueGroup(u32 sourceLine);
|
|||||||
void QueueAbility(u32 sourceLine, struct BattlePokemon *battler, struct AbilityEventContext);
|
void QueueAbility(u32 sourceLine, struct BattlePokemon *battler, struct AbilityEventContext);
|
||||||
void QueueAnimation(u32 sourceLine, u32 type, u32 id, struct AnimationEventContext);
|
void QueueAnimation(u32 sourceLine, u32 type, u32 id, struct AnimationEventContext);
|
||||||
void QueueHP(u32 sourceLine, struct BattlePokemon *battler, struct HPEventContext);
|
void QueueHP(u32 sourceLine, struct BattlePokemon *battler, struct HPEventContext);
|
||||||
|
void QueueSubHit(u32 sourceLine, struct BattlePokemon *battler, struct SubHitEventContext);
|
||||||
void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventContext);
|
void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventContext);
|
||||||
void QueueMessage(u32 sourceLine, const u8 *pattern);
|
void QueueMessage(u32 sourceLine, const u8 *pattern);
|
||||||
void QueueStatus(u32 sourceLine, struct BattlePokemon *battler, struct StatusEventContext);
|
void QueueStatus(u32 sourceLine, struct BattlePokemon *battler, struct StatusEventContext);
|
||||||
|
|||||||
@ -16,6 +16,7 @@ enum Gimmick;
|
|||||||
void TestRunner_Battle_RecordAbilityPopUp(u32 battlerId, enum Ability ability);
|
void TestRunner_Battle_RecordAbilityPopUp(u32 battlerId, enum Ability ability);
|
||||||
void TestRunner_Battle_RecordAnimation(u32 animType, u32 animId);
|
void TestRunner_Battle_RecordAnimation(u32 animType, u32 animId);
|
||||||
void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP);
|
void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP);
|
||||||
|
void TestRunner_Battle_RecordSubHit(u32 battlerId, u32 damage, bool32 broke);
|
||||||
void TestRunner_Battle_RecordExp(u32 battlerId, u32 oldExp, u32 newExp);
|
void TestRunner_Battle_RecordExp(u32 battlerId, u32 oldExp, u32 newExp);
|
||||||
void TestRunner_Battle_RecordMessage(const u8 *message);
|
void TestRunner_Battle_RecordMessage(const u8 *message);
|
||||||
void TestRunner_Battle_RecordStatus1(u32 battlerId, u32 status1);
|
void TestRunner_Battle_RecordStatus1(u32 battlerId, u32 status1);
|
||||||
@ -39,6 +40,7 @@ u32 TestRunner_Battle_GetForcedEnvironment(void);
|
|||||||
#define TestRunner_Battle_RecordAbilityPopUp(...) (void)0
|
#define TestRunner_Battle_RecordAbilityPopUp(...) (void)0
|
||||||
#define TestRunner_Battle_RecordAnimation(...) (void)0
|
#define TestRunner_Battle_RecordAnimation(...) (void)0
|
||||||
#define TestRunner_Battle_RecordHP(...) (void)0
|
#define TestRunner_Battle_RecordHP(...) (void)0
|
||||||
|
#define TestRunner_Battle_RecordSubHit(...) (void)0
|
||||||
#define TestRunner_Battle_RecordExp(...) (void)0
|
#define TestRunner_Battle_RecordExp(...) (void)0
|
||||||
#define TestRunner_Battle_RecordMessage(...) (void)0
|
#define TestRunner_Battle_RecordMessage(...) (void)0
|
||||||
#define TestRunner_Battle_RecordStatus1(...) (void)0
|
#define TestRunner_Battle_RecordStatus1(...) (void)0
|
||||||
|
|||||||
@ -2365,10 +2365,12 @@ static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nex
|
|||||||
{
|
{
|
||||||
if (gDisableStructs[battler].substituteHP >= gBattleStruct->moveDamage[battler])
|
if (gDisableStructs[battler].substituteHP >= gBattleStruct->moveDamage[battler])
|
||||||
{
|
{
|
||||||
|
TestRunner_Battle_RecordSubHit(battler, gBattleStruct->moveDamage[battler], FALSE);
|
||||||
gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler];
|
gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
TestRunner_Battle_RecordSubHit(battler, gDisableStructs[battler].substituteHP, TRUE);
|
||||||
gBattleStruct->moveDamage[battler] = gDisableStructs[battler].substituteHP;
|
gBattleStruct->moveDamage[battler] = gDisableStructs[battler].substituteHP;
|
||||||
gDisableStructs[battler].substituteHP = 0;
|
gDisableStructs[battler].substituteHP = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,4 +69,111 @@ SINGLE_BATTLE_TEST("Substitute's HP cost doesn't trigger effects that trigger on
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, break TRUE")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Level(1); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, subBreak: TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, break FALSE")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Level(100); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, subBreak: FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, records damage")
|
||||||
|
{
|
||||||
|
u16 damage;
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, captureDamage: &damage);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_GT(damage, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, records damage, break FALSE")
|
||||||
|
{
|
||||||
|
u16 damage;
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, captureDamage: &damage, subBreak: FALSE);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_GT(damage, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, records damage, break TRUE")
|
||||||
|
{
|
||||||
|
u16 damage;
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Level(1); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, captureDamage: &damage, subBreak: TRUE);
|
||||||
|
} THEN {
|
||||||
|
EXPECT_GT(damage, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, break TRUE, failing")
|
||||||
|
{
|
||||||
|
KNOWN_FAILING; // For testing purposes
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Level(100); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, subBreak: TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT, break FALSE, failing")
|
||||||
|
{
|
||||||
|
KNOWN_FAILING; // For testing purposes
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Level(1); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_SUBSTITUTE); MOVE(opponent, MOVE_SCRATCH); }
|
||||||
|
} SCENE {
|
||||||
|
SUB_HIT(player, subBreak: FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TO_DO_BATTLE_TEST("Baton Pass passes Substitutes");
|
TO_DO_BATTLE_TEST("Baton Pass passes Substitutes");
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#undef TestRunner_Battle_RecordAbilityPopUp
|
#undef TestRunner_Battle_RecordAbilityPopUp
|
||||||
#undef TestRunner_Battle_RecordAnimation
|
#undef TestRunner_Battle_RecordAnimation
|
||||||
#undef TestRunner_Battle_RecordHP
|
#undef TestRunner_Battle_RecordHP
|
||||||
|
#undef TestRunner_Battle_RecordSubHit
|
||||||
#undef TestRunner_Battle_RecordMessage
|
#undef TestRunner_Battle_RecordMessage
|
||||||
#undef TestRunner_Battle_RecordStatus1
|
#undef TestRunner_Battle_RecordStatus1
|
||||||
#undef TestRunner_Battle_AfterLastTurn
|
#undef TestRunner_Battle_AfterLastTurn
|
||||||
@ -946,6 +947,85 @@ void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s32 TrySubHit(s32 i, s32 n, u32 battlerId, u32 damage, bool32 broke)
|
||||||
|
{
|
||||||
|
struct QueuedSubHitEvent *event;
|
||||||
|
s32 iMax = i + n;
|
||||||
|
for (; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (DATA.queuedEvents[i].type != QUEUED_SUB_HIT_EVENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
event = &DATA.queuedEvents[i].as.subHit;
|
||||||
|
|
||||||
|
if (event->battlerId == battlerId)
|
||||||
|
{
|
||||||
|
if (event->checkBreak)
|
||||||
|
{
|
||||||
|
if (event->breakSub && !broke)
|
||||||
|
return -1;
|
||||||
|
else if (!event->breakSub && broke)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->address <= 0xFFFF)
|
||||||
|
{
|
||||||
|
event->address = damage;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(u16 *)(u32)(event->address) = damage;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestRunner_Battle_RecordSubHit(u32 battlerId, u32 damage, bool32 broke)
|
||||||
|
{
|
||||||
|
s32 queuedEvent;
|
||||||
|
s32 match;
|
||||||
|
struct QueuedEvent *event;
|
||||||
|
|
||||||
|
if (DATA.trial.queuedEvent == DATA.queuedEventsCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event = &DATA.queuedEvents[DATA.trial.queuedEvent];
|
||||||
|
switch (event->groupType)
|
||||||
|
{
|
||||||
|
case QUEUE_GROUP_NONE:
|
||||||
|
case QUEUE_GROUP_ONE_OF:
|
||||||
|
if (TrySubHit(DATA.trial.queuedEvent, event->groupSize, battlerId, damage, broke) != -1)
|
||||||
|
DATA.trial.queuedEvent += event->groupSize;
|
||||||
|
break;
|
||||||
|
case QUEUE_GROUP_NONE_OF:
|
||||||
|
queuedEvent = DATA.trial.queuedEvent;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((match = TrySubHit(queuedEvent, event->groupSize, battlerId, damage, broke)) != -1)
|
||||||
|
{
|
||||||
|
const char *filename = gTestRunnerState.test->filename;
|
||||||
|
u32 line = SourceLine(DATA.queuedEvents[match].sourceLineOffset);
|
||||||
|
Test_ExitWithResult(TEST_RESULT_FAIL, line, ":L%s:%d: Matched SUB_HIT", filename, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
queuedEvent += event->groupSize;
|
||||||
|
if (queuedEvent == DATA.queuedEventsCount)
|
||||||
|
break;
|
||||||
|
|
||||||
|
event = &DATA.queuedEvents[queuedEvent];
|
||||||
|
if (event->groupType == QUEUE_GROUP_NONE_OF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TrySubHit(queuedEvent, event->groupSize, battlerId, damage, broke) != -1)
|
||||||
|
DATA.trial.queuedEvent = queuedEvent + event->groupSize;
|
||||||
|
} while (FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const sBattleActionNames[] =
|
static const char *const sBattleActionNames[] =
|
||||||
{
|
{
|
||||||
[B_ACTION_USE_MOVE] = "MOVE",
|
[B_ACTION_USE_MOVE] = "MOVE",
|
||||||
@ -1505,6 +1585,7 @@ static const char *const sEventTypeMacros[] =
|
|||||||
[QUEUED_ABILITY_POPUP_EVENT] = "ABILITY_POPUP",
|
[QUEUED_ABILITY_POPUP_EVENT] = "ABILITY_POPUP",
|
||||||
[QUEUED_ANIMATION_EVENT] = "ANIMATION",
|
[QUEUED_ANIMATION_EVENT] = "ANIMATION",
|
||||||
[QUEUED_HP_EVENT] = "HP_BAR",
|
[QUEUED_HP_EVENT] = "HP_BAR",
|
||||||
|
[QUEUED_SUB_HIT_EVENT] = "SUB_HIT",
|
||||||
[QUEUED_EXP_EVENT] = "EXPERIENCE_BAR",
|
[QUEUED_EXP_EVENT] = "EXPERIENCE_BAR",
|
||||||
[QUEUED_MESSAGE_EVENT] = "MESSAGE",
|
[QUEUED_MESSAGE_EVENT] = "MESSAGE",
|
||||||
[QUEUED_STATUS_EVENT] = "STATUS_ICON",
|
[QUEUED_STATUS_EVENT] = "STATUS_ICON",
|
||||||
@ -2995,6 +3076,46 @@ void QueueHP(u32 sourceLine, struct BattlePokemon *battler, struct HPEventContex
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QueueSubHit(u32 sourceLine, struct BattlePokemon *battler, struct SubHitEventContext ctx)
|
||||||
|
{
|
||||||
|
s32 battlerId = battler - gBattleMons;
|
||||||
|
bool32 breakSub = FALSE;
|
||||||
|
bool32 checkBreak = FALSE;
|
||||||
|
uintptr_t address;
|
||||||
|
|
||||||
|
INVALID_IF(!STATE->runScene, "SUB_HIT outside of SCENE");
|
||||||
|
if (DATA.queuedEventsCount == MAX_QUEUED_EVENTS)
|
||||||
|
Test_ExitWithResult(TEST_RESULT_ERROR, sourceLine, ":L%s:%d: SUB_HIT exceeds MAX_QUEUED_EVENTS", gTestRunnerState.test->filename, sourceLine);
|
||||||
|
|
||||||
|
address = 0;
|
||||||
|
if (ctx.explicitCaptureDamage)
|
||||||
|
{
|
||||||
|
INVALID_IF(ctx.captureDamage == NULL, "captureDamage is NULL");
|
||||||
|
*ctx.captureDamage = 0;
|
||||||
|
address = (uintptr_t)ctx.captureDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.explicitSubBreak)
|
||||||
|
{
|
||||||
|
checkBreak = TRUE;
|
||||||
|
if (ctx.subBreak)
|
||||||
|
breakSub = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DATA.queuedEvents[DATA.queuedEventsCount++] = (struct QueuedEvent) {
|
||||||
|
.type = QUEUED_SUB_HIT_EVENT,
|
||||||
|
.sourceLineOffset = SourceLineOffset(sourceLine),
|
||||||
|
.groupType = QUEUE_GROUP_NONE,
|
||||||
|
.groupSize = 1,
|
||||||
|
.as = { .subHit = {
|
||||||
|
.battlerId = battlerId,
|
||||||
|
.checkBreak = checkBreak,
|
||||||
|
.breakSub = breakSub,
|
||||||
|
.address = address,
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventContext ctx)
|
void QueueExp(u32 sourceLine, struct BattlePokemon *battler, struct ExpEventContext ctx)
|
||||||
{
|
{
|
||||||
s32 battlerId = battler - gBattleMons;
|
s32 battlerId = battler - gBattleMons;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user