Battle Item Tests + critical fixes + new test macro (#2940)

This commit is contained in:
Eduardo Quezada D'Ottone 2023-05-06 20:43:32 -04:00 committed by GitHub
commit 42445512ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 986 additions and 30 deletions

View File

@ -75,7 +75,9 @@ BattleScript_ItemCureStatus::
BattleScript_ItemHealAndCureStatus:: BattleScript_ItemHealAndCureStatus::
call BattleScript_UseItemMessage call BattleScript_UseItemMessage
itemrestorehp itemrestorehp
curestatus BS_ATTACKER itemcurestatus
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
waitmessage B_WAIT_TIME_LONG
bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_ATTACKER healthbarupdate BS_ATTACKER

View File

@ -45,6 +45,8 @@ enum
RECORDED_PARTY_INDEX, RECORDED_PARTY_INDEX,
RECORDED_BATTLE_PALACE_ACTION, RECORDED_BATTLE_PALACE_ACTION,
RECORDED_ITEM_ID, RECORDED_ITEM_ID,
RECORDED_ITEM_TARGET,
RECORDED_ITEM_MOVE,
}; };
extern u32 gRecordedBattleRngSeed; extern u32 gRecordedBattleRngSeed;

View File

@ -1442,6 +1442,8 @@ static void RecordedOpponentHandleChooseItem(void)
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2;
gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler);
gChosenMovePos = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler);
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted();
} }

View File

@ -1466,6 +1466,8 @@ static void RecordedPlayerHandleChooseItem(void)
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler);
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2;
gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler);
gChosenMovePos = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler);
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted();
} }

View File

@ -265,7 +265,7 @@ static const u8 sText_XFoundOneY[] = _("{B_ATK_NAME_WITH_PREFIX} found\none {B_L
static const u8 sText_SoothingAroma[] = _("A soothing aroma wafted\nthrough the area!"); static const u8 sText_SoothingAroma[] = _("A soothing aroma wafted\nthrough the area!");
static const u8 sText_ItemsCantBeUsedNow[] = _("Items can't be used now.{PAUSE 64}"); static const u8 sText_ItemsCantBeUsedNow[] = _("Items can't be used now.{PAUSE 64}");
static const u8 sText_ForXCommaYZ[] = _("For {B_SCR_ACTIVE_NAME_WITH_PREFIX},\n{B_LAST_ITEM} {B_BUFF1}"); static const u8 sText_ForXCommaYZ[] = _("For {B_SCR_ACTIVE_NAME_WITH_PREFIX},\n{B_LAST_ITEM} {B_BUFF1}");
static const u8 sText_PkmnUsedXToGetPumped[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used\n{B_LAST_ITEM} to get pumped!"); static const u8 sText_PkmnUsedXToGetPumped[] = _("{B_ACTIVE_NAME_WITH_PREFIX} used\n{B_LAST_ITEM} to get pumped!");
static const u8 sText_PkmnLostFocus[] = _("{B_ATK_NAME_WITH_PREFIX} lost its\nfocus and couldn't move!"); static const u8 sText_PkmnLostFocus[] = _("{B_ATK_NAME_WITH_PREFIX} lost its\nfocus and couldn't move!");
static const u8 sText_PkmnWasDraggedOut[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndragged out!\p"); static const u8 sText_PkmnWasDraggedOut[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndragged out!\p");
static const u8 sText_TheWallShattered[] = _("The wall shattered!"); static const u8 sText_TheWallShattered[] = _("The wall shattered!");

View File

@ -16515,8 +16515,7 @@ void BS_ItemIncreaseStat(void) {
void BS_ItemRestorePP(void) { void BS_ItemRestorePP(void) {
NATIVE_ARGS(); NATIVE_ARGS();
const u8 *effect = GetItemEffect(gLastUsedItem); const u8 *effect = GetItemEffect(gLastUsedItem);
u32 i, pp, maxPP, moveId; u32 i, pp, maxPP, moveId, loopEnd;
u32 loopEnd = MAX_MON_MOVES;
u32 battlerId = MAX_BATTLERS_COUNT; u32 battlerId = MAX_BATTLERS_COUNT;
struct Pokemon *mon = (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) ? &gPlayerParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]] : &gEnemyParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]]; struct Pokemon *mon = (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) ? &gPlayerParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]] : &gEnemyParty[gBattleStruct->itemPartyIndex[gBattlerAttacker]];
@ -16526,6 +16525,11 @@ void BS_ItemRestorePP(void) {
i = gChosenMovePos; i = gChosenMovePos;
loopEnd = gChosenMovePos + 1; loopEnd = gChosenMovePos + 1;
} }
else
{
i = 0;
loopEnd = MAX_MON_MOVES;
}
// Check if the recipient is an active battler. // Check if the recipient is an active battler.
if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker]) if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker])
@ -16535,7 +16539,7 @@ void BS_ItemRestorePP(void) {
battlerId = BATTLE_PARTNER(gBattlerAttacker); battlerId = BATTLE_PARTNER(gBattlerAttacker);
// Heal PP! // Heal PP!
for (i = 0; i < loopEnd; i++) for (; i < loopEnd; i++)
{ {
pp = GetMonData(mon, MON_DATA_PP1 + i, NULL); pp = GetMonData(mon, MON_DATA_PP1 + i, NULL);
moveId = GetMonData(mon, MON_DATA_MOVE1 + i, NULL); moveId = GetMonData(mon, MON_DATA_MOVE1 + i, NULL);

View File

@ -526,7 +526,7 @@ const struct Item gItems[] =
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU, .type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_Medicine, .fieldUseFunc = ItemUseOutOfBattle_Medicine,
.battleUsage = EFFECT_ITEM_RESTORE_HP, .battleUsage = EFFECT_ITEM_CURE_STATUS,
.flingPower = 30, .flingPower = 30,
}, },

View File

@ -0,0 +1,339 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Paralyze Heal heals a battler from being paralyzed")
{
GIVEN {
ASSUME(gItems[ITEM_PARALYZE_HEAL].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_PARALYSIS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_PARALYZE_HEAL, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Antidote heals a battler from being poisoned")
{
GIVEN {
ASSUME(gItems[ITEM_ANTIDOTE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ANTIDOTE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Antidote heals a battler from being badly poisoned")
{
GIVEN {
ASSUME(gItems[ITEM_ANTIDOTE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_TOXIC_POISON); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ANTIDOTE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Awakening heals a battler from being asleep")
{
GIVEN {
ASSUME(gItems[ITEM_AWAKENING].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_AWAKENING, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Burn Heal heals a battler from being burned")
{
GIVEN {
ASSUME(gItems[ITEM_BURN_HEAL].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_BURN_HEAL, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Ice Heal heals a battler from being paralyzed")
{
GIVEN {
ASSUME(gItems[ITEM_ICE_HEAL].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ICE_HEAL, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Full Heal heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_FULL_HEAL].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_FULL_HEAL, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Heal Powder heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_HEAL_POWDER].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_HEAL_POWDER, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Pewter Crunchies heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_PEWTER_CRUNCHIES].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_PEWTER_CRUNCHIES, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Lava Cookies heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_LAVA_COOKIE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_LAVA_COOKIE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Rage Candy Bar heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_RAGE_CANDY_BAR].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_RAGE_CANDY_BAR, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Old Gateu heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_OLD_GATEAU].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_OLD_GATEAU, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Casteliacone heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_CASTELIACONE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_CASTELIACONE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Lumiose Galette heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_LUMIOSE_GALETTE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_LUMIOSE_GALETTE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");;
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Shalour Sable heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_SHALOUR_SABLE].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_SHALOUR_SABLE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Big Malasada heals a battler from any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_BIG_MALASADA].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { Status1(status); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { USE_ITEM(player, ITEM_BIG_MALASADA, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Full Heal, Heal Powder and Local Specialties heal a battler from being confused")
{
u16 item;
PARAMETRIZE { item = ITEM_FULL_HEAL; }
PARAMETRIZE { item = ITEM_HEAL_POWDER; }
PARAMETRIZE { item = ITEM_PEWTER_CRUNCHIES; }
PARAMETRIZE { item = ITEM_LAVA_COOKIE; }
PARAMETRIZE { item = ITEM_RAGE_CANDY_BAR; }
PARAMETRIZE { item = ITEM_OLD_GATEAU; }
PARAMETRIZE { item = ITEM_CASTELIACONE; }
PARAMETRIZE { item = ITEM_LUMIOSE_GALETTE; }
PARAMETRIZE { item = ITEM_SHALOUR_SABLE; }
PARAMETRIZE { item = ITEM_BIG_MALASADA; }
GIVEN {
ASSUME(gItems[item].battleUsage == EFFECT_ITEM_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GENGAR);
} WHEN {
TURN { MOVE(opponent, MOVE_CONFUSE_RAY); }
TURN { USE_ITEM(player, item, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its status healed!");
} THEN {
EXPECT_EQ(player->status2, STATUS1_NONE); // because we dont have STATUS2_NONE
}
}

View File

@ -0,0 +1,43 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures any primary status")
{
u16 status;
PARAMETRIZE{ status = STATUS1_BURN; }
PARAMETRIZE{ status = STATUS1_FREEZE; }
PARAMETRIZE{ status = STATUS1_PARALYSIS; }
PARAMETRIZE{ status = STATUS1_POISON; }
PARAMETRIZE{ status = STATUS1_TOXIC_POISON; }
PARAMETRIZE{ status = STATUS1_SLEEP; }
GIVEN {
ASSUME(gItems[ITEM_FULL_RESTORE].battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { HP(1); MaxHP(300); Status1(status); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN{ USE_ITEM(player, ITEM_FULL_RESTORE, partyIndex: 0); }
} SCENE {
MESSAGE("Wobbuffet had its HP restored!");
} THEN {
EXPECT_EQ(player->hp, player->maxHP);
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Full Restore restores a battler's HP and cures confusion")
{
GIVEN {
ASSUME(gItems[ITEM_FULL_RESTORE].battleUsage == EFFECT_ITEM_HEAL_AND_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET) { HP(1); MaxHP(300);};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN{ MOVE(opponent, MOVE_CONFUSE_RAY); }
TURN{ USE_ITEM(player, ITEM_FULL_RESTORE, partyIndex: 0); }
TURN{ MOVE(player, MOVE_TACKLE); }
} SCENE {
MESSAGE("Wobbuffet had its HP restored!");
NONE_OF { MESSAGE("Wobbuffet is confused!"); }
} THEN {
EXPECT_EQ(player->hp, player->maxHP);
}
}

View File

@ -1,7 +1,7 @@
#include "global.h" #include "global.h"
#include "test_battle.h" #include "test_battle.h"
SINGLE_BATTLE_TEST("X-Attack sharply raises battler's Attack stat", s16 damage) SINGLE_BATTLE_TEST("X Attack sharply raises battler's Attack stat", s16 damage)
{ {
u16 useItem; u16 useItem;
PARAMETRIZE { useItem = FALSE; } PARAMETRIZE { useItem = FALSE; }
@ -23,3 +23,231 @@ SINGLE_BATTLE_TEST("X-Attack sharply raises battler's Attack stat", s16 damage)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
} }
} }
SINGLE_BATTLE_TEST("X Defense sharply raises battler's Defense stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_X_DEFENSE].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_X_DEFENSE); }
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
MESSAGE("Foe Wobbuffet used Tackle!");
HP_BAR(player, captureDamage: &results[i].damage);
} FINALLY {
if (B_X_ITEMS_BUFF >= GEN_7)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
else
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.66), results[1].damage);
}
}
SINGLE_BATTLE_TEST("X Sp. Atk sharply raises battler's Sp. Attack stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_X_SP_ATK].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_X_SP_ATK); }
TURN { MOVE(player, MOVE_DISARMING_VOICE); }
} SCENE {
MESSAGE("Wobbuffet used DisrmngVoice!");
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
if (B_X_ITEMS_BUFF >= GEN_7)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
else
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
SINGLE_BATTLE_TEST("X Sp. Def sharply raises battler's Sp. Defense stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_X_SP_DEF].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_X_SP_DEF); }
TURN { MOVE(opponent, MOVE_DISARMING_VOICE); }
} SCENE {
MESSAGE("Foe Wobbuffet used DisrmngVoice!");
HP_BAR(player, captureDamage: &results[i].damage);
} FINALLY {
if (B_X_ITEMS_BUFF >= GEN_7)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
else
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.66), results[1].damage);
}
}
SINGLE_BATTLE_TEST("X Speed sharply raises battler's Speed stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_X_SPEED].battleUsage == EFFECT_ITEM_INCREASE_STAT);
if (B_X_ITEMS_BUFF >= GEN_7)
{
PLAYER(SPECIES_WOBBUFFET) { Speed(3); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(4); };
}
else
{
PLAYER(SPECIES_WOBBUFFET) { Speed(4); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); };
}
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_X_SPEED); }
TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_TACKLE); }
} SCENE {
if (useItem)
{
MESSAGE("Wobbuffet used Tackle!");
MESSAGE("Foe Wobbuffet used Tackle!");
} else
{
MESSAGE("Foe Wobbuffet used Tackle!");
MESSAGE("Wobbuffet used Tackle!");
}
}
}
SINGLE_BATTLE_TEST("X Accuracy sharply raises battler's Accuracy stat", s16 damage)
{
ASSUME(gBattleMoves[MOVE_SING].accuracy == 55);
if (B_X_ITEMS_BUFF >= GEN_7)
PASSES_RANDOMLY(gBattleMoves[MOVE_SING].accuracy * 5 / 3, 100, RNG_ACCURACY);
else
PASSES_RANDOMLY(gBattleMoves[MOVE_SING].accuracy * 4 / 3, 100, RNG_ACCURACY);
GIVEN {
ASSUME(gItems[ITEM_X_ACCURACY].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_X_ACCURACY); }
TURN { MOVE(player, MOVE_SING); }
} SCENE {
MESSAGE("Wobbuffet used Sing!");
MESSAGE("Foe Wobbuffet fell asleep!");
}
}
SINGLE_BATTLE_TEST("Max Mushrooms raises battler's Attack stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_MAX_MUSHROOMS].battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_MAX_MUSHROOMS); }
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
MESSAGE("Wobbuffet used Tackle!");
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Max Mushrooms raises battler's Defense stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_MAX_MUSHROOMS].battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_MAX_MUSHROOMS); }
TURN { MOVE(opponent, MOVE_TACKLE); }
} SCENE {
MESSAGE("Foe Wobbuffet used Tackle!");
HP_BAR(player, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.66), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Max Mushrooms raises battler's Sp. Attack stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_MAX_MUSHROOMS].battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_MAX_MUSHROOMS); }
TURN { MOVE(player, MOVE_DISARMING_VOICE); }
} SCENE {
MESSAGE("Wobbuffet used DisrmngVoice!");
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Max Mushrooms battler's Sp. Defense stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_MAX_MUSHROOMS].battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_MAX_MUSHROOMS); }
TURN { MOVE(opponent, MOVE_DISARMING_VOICE); }
} SCENE {
MESSAGE("Foe Wobbuffet used DisrmngVoice!");
HP_BAR(player, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.66), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Max Mushrooms raises battler's Speed stat", s16 damage)
{
u16 useItem;
PARAMETRIZE { useItem = FALSE; }
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItems[ITEM_MAX_MUSHROOMS].battleUsage == EFFECT_ITEM_INCREASE_ALL_STATS);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); };
} WHEN {
if (useItem) TURN { USE_ITEM(player, ITEM_MAX_MUSHROOMS); }
TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_TACKLE); }
} SCENE {
if (useItem)
{
MESSAGE("Wobbuffet used Tackle!");
MESSAGE("Foe Wobbuffet used Tackle!");
} else
{
MESSAGE("Foe Wobbuffet used Tackle!");
MESSAGE("Wobbuffet used Tackle!");
}
}
}

View File

@ -1,37 +1,186 @@
#include "global.h" #include "global.h"
#include "test_battle.h" #include "test_battle.h"
#define TEST_HP 1
#define MAX_HP 400
SINGLE_BATTLE_TEST("Potion restores a battler's HP by 20") SINGLE_BATTLE_TEST("Potion restores a battler's HP by 20")
{ {
s16 damage;
GIVEN { GIVEN {
ASSUME(gItems[ITEM_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP); ASSUME(gItems[ITEM_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(100); } PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
TURN { USE_ITEM(player, ITEM_POTION, partyIndex: 0); } TURN { USE_ITEM(player, ITEM_POTION, partyIndex: 0); }
} SCENE { } SCENE {
HP_BAR(player, captureDamage: &damage); HP_BAR(player, hp: TEST_HP + 20);
} FINALLY {
EXPECT_EQ(damage, -20);
} }
} }
SINGLE_BATTLE_TEST("Sitrus Berry restores a battler's HP") SINGLE_BATTLE_TEST("Super Potion restores a battler's HP by 60")
{
GIVEN {
ASSUME(gItems[ITEM_SUPER_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_SUPER_POTION, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 60);
}
}
SINGLE_BATTLE_TEST("Hyper Potion restores a battler's HP by 120")
{
GIVEN {
ASSUME(gItems[ITEM_HYPER_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_HYPER_POTION, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 120);
}
}
SINGLE_BATTLE_TEST("Max Potion restores a battler's HP fully")
{
GIVEN {
ASSUME(gItems[ITEM_MAX_POTION].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_MAX_POTION, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: MAX_HP);
}
}
SINGLE_BATTLE_TEST("Fresh Water restores a battler's HP by 30")
{
GIVEN {
ASSUME(gItems[ITEM_FRESH_WATER].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_FRESH_WATER, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 30);
}
}
SINGLE_BATTLE_TEST("Soda Pop restores a battler's HP by 50")
{
GIVEN {
ASSUME(gItems[ITEM_SODA_POP].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_SODA_POP, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 50);
}
}
SINGLE_BATTLE_TEST("Lemonade restores a battler's HP by 70")
{
GIVEN {
ASSUME(gItems[ITEM_LEMONADE].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_LEMONADE, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 70);
}
}
SINGLE_BATTLE_TEST("Moomoo Milk restores a battler's HP by 100")
{
GIVEN {
ASSUME(gItems[ITEM_MOOMOO_MILK].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_MOOMOO_MILK, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 100);
}
}
SINGLE_BATTLE_TEST("Energy Powder restores a battler's HP by 60(50)")
{
GIVEN {
ASSUME(gItems[ITEM_ENERGY_POWDER].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ENERGY_POWDER, partyIndex: 0); }
} SCENE {
if (I_HEALTH_RECOVERY >= GEN_7)
HP_BAR(player, hp: TEST_HP + 60);
else
HP_BAR(player, hp: TEST_HP + 50);
}
}
SINGLE_BATTLE_TEST("Energy Root restores a battler's HP by 120(200)")
{
GIVEN {
ASSUME(gItems[ITEM_ENERGY_ROOT].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ENERGY_ROOT, partyIndex: 0); }
} SCENE {
if (I_HEALTH_RECOVERY >= GEN_7)
HP_BAR(player, hp: TEST_HP + 120);
else
HP_BAR(player, hp: TEST_HP + 200);
}
}
SINGLE_BATTLE_TEST("Sweet Heart restores a battler's HP by 20")
{
GIVEN {
ASSUME(gItems[ITEM_SWEET_HEART].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_SWEET_HEART, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 20);
}
}
SINGLE_BATTLE_TEST("Oran Berry restores a battler's HP by 10")
{
GIVEN {
ASSUME(gItems[ITEM_ORAN_BERRY].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ORAN_BERRY, partyIndex: 0); }
} SCENE {
HP_BAR(player, hp: TEST_HP + 10);
}
}
SINGLE_BATTLE_TEST("Sitrus Berry restores a battler's HP by 25% of its max HP(30HP flat)")
{ {
s16 damage;
GIVEN { GIVEN {
ASSUME(gItems[ITEM_SITRUS_BERRY].battleUsage == EFFECT_ITEM_RESTORE_HP); ASSUME(gItems[ITEM_SITRUS_BERRY].battleUsage == EFFECT_ITEM_RESTORE_HP);
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(100); } PLAYER(SPECIES_WOBBUFFET) { HP(TEST_HP); MaxHP(MAX_HP); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
TURN { USE_ITEM(player, ITEM_SITRUS_BERRY, partyIndex: 0); } TURN { USE_ITEM(player, ITEM_SITRUS_BERRY, partyIndex: 0); }
} SCENE { } SCENE {
HP_BAR(player, captureDamage: &damage);
} FINALLY {
if (I_SITRUS_BERRY_HEAL >= GEN_4) if (I_SITRUS_BERRY_HEAL >= GEN_4)
EXPECT_EQ(damage, -25); HP_BAR(player, hp: TEST_HP + MAX_HP * 0.25);
else else
EXPECT_EQ(damage, -30); HP_BAR(player, hp: TEST_HP + 30);
} }
} }
#undef TEST_HP
#undef MAX_HP

View File

@ -1,19 +1,66 @@
#include "global.h" #include "global.h"
#include "test_battle.h" #include "test_battle.h"
SINGLE_BATTLE_TEST("Ether restores the PP of one of a battler's moves") SINGLE_BATTLE_TEST("Ether restores the PP of one of a battler's moves by 10 ")
{ {
GIVEN { GIVEN {
ASSUME(gItems[ITEM_ETHER].battleUsage == EFFECT_ITEM_RESTORE_PP); ASSUME(gItems[ITEM_ETHER].battleUsage == EFFECT_ITEM_RESTORE_PP);
ASSUME(gItems[ITEM_ETHER].type == ITEM_USE_PARTY_MENU_MOVES); ASSUME(gItems[ITEM_ETHER].type == ITEM_USE_PARTY_MENU_MOVES);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_CONFUSION); } PLAYER(SPECIES_WOBBUFFET) { MovesWithPP({MOVE_TACKLE, 0}, {MOVE_CONFUSION, 20}); }
OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET);
} WHEN { } WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
TURN { MOVE(player, MOVE_CONFUSION); }
TURN { USE_ITEM(player, ITEM_ETHER, partyIndex: 0, move: MOVE_TACKLE); } TURN { USE_ITEM(player, ITEM_ETHER, partyIndex: 0, move: MOVE_TACKLE); }
} FINALLY { } THEN {
EXPECT_EQ(player->pp[0], 35); EXPECT_EQ(player->pp[0], 10);
EXPECT_EQ(player->pp[1], 24); EXPECT_EQ(player->pp[1], 20);
}
}
SINGLE_BATTLE_TEST("Max Ether restores the PP of one of a battler's moves fully")
{
GIVEN {
ASSUME(gItems[ITEM_MAX_ETHER].battleUsage == EFFECT_ITEM_RESTORE_PP);
ASSUME(gItems[ITEM_MAX_ETHER].type == ITEM_USE_PARTY_MENU_MOVES);
PLAYER(SPECIES_WOBBUFFET) { MovesWithPP({MOVE_TACKLE, 0}, {MOVE_CONFUSION, 20}); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_MAX_ETHER, partyIndex: 0, move: MOVE_TACKLE); }
} THEN {
EXPECT_EQ(player->pp[0], 35);
EXPECT_EQ(player->pp[1], 20);
}
}
SINGLE_BATTLE_TEST("Elixir restores the PP of all of a battler's moves by 10")
{
GIVEN {
ASSUME(gItems[ITEM_ELIXIR].battleUsage == EFFECT_ITEM_RESTORE_PP);
ASSUME(gItems[ITEM_ELIXIR].type == ITEM_USE_PARTY_MENU);
PLAYER(SPECIES_WOBBUFFET) { MovesWithPP({MOVE_TACKLE, 0}, {MOVE_CONFUSION, 0}, {MOVE_SCRATCH, 0}, {MOVE_GROWL, 0}); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_ELIXIR, partyIndex: 0); }
} THEN {
EXPECT_EQ(player->pp[0], 10);
EXPECT_EQ(player->pp[1], 10);
EXPECT_EQ(player->pp[2], 10);
EXPECT_EQ(player->pp[3], 10);
}
}
SINGLE_BATTLE_TEST("Max Elixir restores the PP of all of a battler's moves fully")
{
GIVEN {
ASSUME(gItems[ITEM_MAX_ELIXIR].battleUsage == EFFECT_ITEM_RESTORE_PP);
ASSUME(gItems[ITEM_MAX_ELIXIR].type == ITEM_USE_PARTY_MENU);
PLAYER(SPECIES_WOBBUFFET) { MovesWithPP({MOVE_TACKLE, 0}, {MOVE_CONFUSION, 0}, {MOVE_SCRATCH, 0}, {MOVE_GROWL, 0}); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_MAX_ELIXIR, partyIndex: 0); }
} THEN {
EXPECT_EQ(player->pp[0], 35);
EXPECT_EQ(player->pp[1], 25);
EXPECT_EQ(player->pp[2], 35);
EXPECT_EQ(player->pp[3], 40);
} }
} }

78
test/item_effect_revive.c Normal file
View File

@ -0,0 +1,78 @@
#include "global.h"
#include "test_battle.h"
#define MAX_HP 200
SINGLE_BATTLE_TEST("Revive restores a fainted battler's HP to half")
{
GIVEN {
ASSUME(gItems[ITEM_REVIVE].battleUsage == EFFECT_ITEM_REVIVE);
PLAYER(SPECIES_WYNAUT) { HP(1); MaxHP(MAX_HP); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
TURN { USE_ITEM(player, ITEM_REVIVE, partyIndex: 0); }
TURN { SWITCH(player, 0); }
} SCENE {
MESSAGE("Wynaut had its HP restored!");
} THEN {
EXPECT_EQ(player->hp, MAX_HP/2);
}
}
SINGLE_BATTLE_TEST("Max Revive restores a fainted battler's HP fully")
{
GIVEN {
ASSUME(gItems[ITEM_MAX_REVIVE].battleUsage == EFFECT_ITEM_REVIVE);
PLAYER(SPECIES_WYNAUT) { HP(1); MaxHP(MAX_HP); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
TURN { USE_ITEM(player, ITEM_MAX_REVIVE, partyIndex: 0); }
TURN { SWITCH(player, 0); }
} SCENE {
MESSAGE("Wynaut had its HP restored!");
} THEN {
EXPECT_EQ(player->hp, MAX_HP);
}
}
SINGLE_BATTLE_TEST("Revival Herb restores a fainted battler's HP fully")
{
GIVEN {
ASSUME(gItems[ITEM_REVIVAL_HERB].battleUsage == EFFECT_ITEM_REVIVE);
PLAYER(SPECIES_WYNAUT) { HP(1); MaxHP(MAX_HP); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
TURN { USE_ITEM(player, ITEM_REVIVAL_HERB, partyIndex: 0); }
TURN { SWITCH(player, 0); }
} SCENE {
MESSAGE("Wynaut had its HP restored!");
} THEN {
EXPECT_EQ(player->hp, MAX_HP);
}
}
SINGLE_BATTLE_TEST("Max Honey restores a fainted battler's HP fully")
{
GIVEN {
ASSUME(gItems[ITEM_MAX_HONEY].battleUsage == EFFECT_ITEM_REVIVE);
PLAYER(SPECIES_WYNAUT) { HP(1); MaxHP(MAX_HP); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
TURN { USE_ITEM(player, ITEM_MAX_HONEY, partyIndex: 0); }
TURN { SWITCH(player, 0); }
} SCENE {
MESSAGE("Wynaut had its HP restored!");
} THEN {
EXPECT_EQ(player->hp, MAX_HP);
}
}
#undef MAX_HP

View File

@ -0,0 +1,21 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Dire Hit increases a battler's critical hit chance by 2 stages")
{
ASSUME(B_CRIT_CHANCE >= GEN_7);
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(gItems[ITEM_DIRE_HIT].battleUsage == EFFECT_ITEM_SET_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_DIRE_HIT, partyIndex: 0); }
TURN { MOVE(player, MOVE_SCRATCH); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, player);
MESSAGE("Wobbuffet used Dire Hit to get pumped!");
MESSAGE("Wobbuffet used Scratch!");
MESSAGE("A critical hit!");
}
}

View File

@ -0,0 +1,19 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Guard Spec. sets Mist effect on the battlers side")
{
GIVEN {
ASSUME(gItems[ITEM_GUARD_SPEC].battleUsage == EFFECT_ITEM_SET_MIST);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { USE_ITEM(player, ITEM_GUARD_SPEC, partyIndex: 0); }
TURN { MOVE(opponent, MOVE_GROWL); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIST, player);
MESSAGE("Ally became shrouded in MIST!");
MESSAGE("Foe Wobbuffet used Growl!");
MESSAGE("Wobbuffet is protected by MIST!");
}
}

View File

@ -712,6 +712,11 @@ void Randomly(u32 sourceLine, u32 passes, u32 trials, struct RandomlyContext);
/* Given */ /* Given */
struct moveWithPP {
u16 moveId;
u8 pp;
};
#define GIVEN for (; gBattleTestRunnerState->runGiven; gBattleTestRunnerState->runGiven = FALSE) #define GIVEN for (; gBattleTestRunnerState->runGiven; gBattleTestRunnerState->runGiven = FALSE)
#define RNGSeed(seed) RNGSeed_(__LINE__, seed) #define RNGSeed(seed) RNGSeed_(__LINE__, seed)
@ -732,6 +737,7 @@ void Randomly(u32 sourceLine, u32 passes, u32 trials, struct RandomlyContext);
#define Speed(speed) Speed_(__LINE__, speed) #define Speed(speed) Speed_(__LINE__, speed)
#define Item(item) Item_(__LINE__, item) #define Item(item) Item_(__LINE__, item)
#define Moves(move1, ...) Moves_(__LINE__, (const u16 [MAX_MON_MOVES]) { move1, __VA_ARGS__ }) #define Moves(move1, ...) Moves_(__LINE__, (const u16 [MAX_MON_MOVES]) { move1, __VA_ARGS__ })
#define MovesWithPP(movewithpp1, ...) MovesWithPP_(__LINE__, (struct moveWithPP[MAX_MON_MOVES]) {movewithpp1, __VA_ARGS__})
#define Friendship(friendship) Friendship_(__LINE__, friendship) #define Friendship(friendship) Friendship_(__LINE__, friendship)
#define Status1(status1) Status1_(__LINE__, status1) #define Status1(status1) Status1_(__LINE__, status1)
@ -752,6 +758,7 @@ void SpDefense_(u32 sourceLine, u32 spDefense);
void Speed_(u32 sourceLine, u32 speed); void Speed_(u32 sourceLine, u32 speed);
void Item_(u32 sourceLine, u32 item); void Item_(u32 sourceLine, u32 item);
void Moves_(u32 sourceLine, const u16 moves[MAX_MON_MOVES]); void Moves_(u32 sourceLine, const u16 moves[MAX_MON_MOVES]);
void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES]);
void Friendship_(u32 sourceLine, u32 friendship); void Friendship_(u32 sourceLine, u32 friendship);
void Status1_(u32 sourceLine, u32 status1); void Status1_(u32 sourceLine, u32 status1);

View File

@ -1164,6 +1164,21 @@ void Moves_(u32 sourceLine, const u16 moves[MAX_MON_MOVES])
DATA.explicitMoves[DATA.currentSide] |= 1 << DATA.currentPartyIndex; DATA.explicitMoves[DATA.currentSide] |= 1 << DATA.currentPartyIndex;
} }
void MovesWithPP_(u32 sourceLine, struct moveWithPP moveWithPP[MAX_MON_MOVES])
{
s32 i;
INVALID_IF(!DATA.currentMon, "Moves outside of PLAYER/OPPONENT");
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moveWithPP[i].moveId == MOVE_NONE)
break;
INVALID_IF(moveWithPP[i].moveId >= MOVES_COUNT, "Illegal move: %d", &moveWithPP[i].moveId);
SetMonData(DATA.currentMon, MON_DATA_MOVE1 + i, &moveWithPP[i].moveId);
SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &moveWithPP[i].pp);
}
DATA.explicitMoves[DATA.currentSide] |= 1 << DATA.currentPartyIndex;
}
void Friendship_(u32 sourceLine, u32 friendship) void Friendship_(u32 sourceLine, u32 friendship)
{ {
INVALID_IF(!DATA.currentMon, "Friendship outside of PLAYER/OPPONENT"); INVALID_IF(!DATA.currentMon, "Friendship outside of PLAYER/OPPONENT");
@ -1542,10 +1557,8 @@ void UseItem(u32 sourceLine, struct BattlePokemon *battler, struct ItemContext c
PushBattlerAction(sourceLine, battlerId, RECORDED_ACTION_TYPE, B_ACTION_USE_ITEM); PushBattlerAction(sourceLine, battlerId, RECORDED_ACTION_TYPE, B_ACTION_USE_ITEM);
PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, (ctx.itemId >> 8) & 0xFF); PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, (ctx.itemId >> 8) & 0xFF);
PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, ctx.itemId & 0xFF); PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_ID, ctx.itemId & 0xFF);
if (ctx.explicitPartyIndex) PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_TARGET, ctx.partyIndex);
gBattleStruct->itemPartyIndex[battlerId] = ctx.partyIndex; PushBattlerAction(sourceLine, battlerId, RECORDED_ITEM_MOVE, i);
if (ctx.explicitMove)
gBattleStruct->itemPartyIndex[battlerId] = i;
DATA.actionBattlers |= 1 << battlerId; DATA.actionBattlers |= 1 << battlerId;
} }