Merge branch 'master' of https://github.com/rh-hideout/pokeemerald-expansion into rh-hideout-master
This commit is contained in:
commit
75a10b6baa
@ -288,7 +288,7 @@
|
||||
.byte 0x31
|
||||
.4byte \template
|
||||
.if \anim_battler == ANIM_TARGET
|
||||
.byte 0x80 | (\subpriority_offset & 0x7F)
|
||||
.byte ANIMSPRITE_IS_TARGET | (\subpriority_offset & 0x7F)
|
||||
.else
|
||||
.byte (\subpriority_offset & 0x7F)
|
||||
.endif
|
||||
@ -304,7 +304,7 @@
|
||||
.byte 0x32
|
||||
.4byte \template
|
||||
.if \anim_battler == ANIM_TARGET
|
||||
.byte 0x80 | (\subpriority_offset & 0x7F)
|
||||
.byte ANIMSPRITE_IS_TARGET | (\subpriority_offset & 0x7F)
|
||||
.else
|
||||
.byte (\subpriority_offset & 0x7F)
|
||||
.endif
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
F(CONFUSION_SELF_DMG_CHANCE, confusionSelfDmgChance, (u32, GEN_COUNT - 1)) \
|
||||
F(MULTI_HIT_CHANCE, multiHitChance, (u32, GEN_COUNT - 1)) \
|
||||
F(WHITEOUT_MONEY, whiteoutMoney, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
|
||||
F(LIGHT_BALL_ATTACK_BOOST, lightBallAttackBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
|
||||
F(LIGHT_BALL_ATTACK_BOOST, lightBallAttackBoost, (u32, GEN_COUNT - 1)) \
|
||||
/* Experience settings */ \
|
||||
F(EXP_CATCH, expCatch, (u32, GEN_COUNT - 1)) \
|
||||
F(TRAINER_EXP_MULTIPLIER, trainerExpMultiplier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
|
||||
|
||||
@ -2049,9 +2049,16 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_FOLLOW_ME:
|
||||
if (!hasPartner
|
||||
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)
|
||||
|| (aiData->partnerMove != MOVE_NONE && IsBattleMoveStatus(aiData->partnerMove))
|
||||
|| gBattleStruct->monToSwitchIntoId[BATTLE_PARTNER(battlerAtk)] != PARTY_SIZE)
|
||||
ADJUST_SCORE(-20);
|
||||
break;
|
||||
case EFFECT_HELPING_HAND:
|
||||
if (!hasPartner
|
||||
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)
|
||||
|| aiData->abilities[BATTLE_PARTNER(battlerAtk)] == ABILITY_GOOD_AS_GOLD
|
||||
|| (aiData->partnerMove != MOVE_NONE && IsBattleMoveStatus(aiData->partnerMove))
|
||||
|| gBattleStruct->monToSwitchIntoId[BATTLE_PARTNER(battlerAtk)] != PARTY_SIZE) //Partner is switching out.
|
||||
ADJUST_SCORE(-20);
|
||||
@ -3152,6 +3159,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_HELPING_HAND:
|
||||
if (!hasPartner
|
||||
|| !HasDamagingMove(battlerAtkPartner)
|
||||
|| aiData->abilities[battlerAtkPartner] == ABILITY_GOOD_AS_GOLD
|
||||
|| (aiData->partnerMove != MOVE_NONE && IsBattleMoveStatus(aiData->partnerMove)))
|
||||
{
|
||||
ADJUST_SCORE(WORST_EFFECT);
|
||||
|
||||
@ -5158,7 +5158,7 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun
|
||||
typeMultiplier = CalcPartyMonTypeEffectivenessMultiplier(moves[i * 4 + j], targetSpecies, targetAbility);
|
||||
if (typeMultiplier == UQ_4_12(0))
|
||||
moveScores[i * MAX_MON_MOVES + j] += 0;
|
||||
else if (typeMultiplier >= UQ_4_12(2))
|
||||
else if (typeMultiplier >= UQ_4_12(2.0))
|
||||
moveScores[i * MAX_MON_MOVES + j] += movePower * 2;
|
||||
else if (typeMultiplier <= UQ_4_12(0.5))
|
||||
moveScores[i * MAX_MON_MOVES + j] += movePower / 2;
|
||||
|
||||
@ -305,7 +305,7 @@ const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT] =
|
||||
{
|
||||
[TRAINER_CLASS_PKMN_TRAINER_1] = { _("宝可梦训练家") },
|
||||
[TRAINER_CLASS_PKMN_TRAINER_2] = { _("宝可梦训练家") },
|
||||
[TRAINER_CLASS_HIKER] = { _("登山男"), 10 },
|
||||
[TRAINER_CLASS_HIKER] = { _("登山男"), 10, B_TRAINER_CLASS_POKE_BALLS >= GEN_8 ? BALL_ULTRA : BALL_POKE },
|
||||
[TRAINER_CLASS_TEAM_AQUA] = { _("海洋队") },
|
||||
[TRAINER_CLASS_PKMN_BREEDER] = { _("宝可梦培育家"), 10, B_TRAINER_CLASS_POKE_BALLS >= GEN_8 ? BALL_HEAL : BALL_FRIEND },
|
||||
[TRAINER_CLASS_COOLTRAINER] = { _("精英训练家"), 12, BALL_ULTRA },
|
||||
@ -324,7 +324,7 @@ const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT] =
|
||||
[TRAINER_CLASS_TUBER_F] = { _("泳圈女孩"), 1 },
|
||||
[TRAINER_CLASS_TUBER_M] = { _("泳圈男孩"), 1 },
|
||||
[TRAINER_CLASS_LADY] = { _("千金小姐"), 50 },
|
||||
[TRAINER_CLASS_BEAUTY] = { _("大姐姐"), 20 },
|
||||
[TRAINER_CLASS_BEAUTY] = { _("大姐姐"), 20, B_TRAINER_CLASS_POKE_BALLS >= GEN_8 ? BALL_GREAT : BALL_POKE },
|
||||
[TRAINER_CLASS_RICH_BOY] = { _("富家少爷"), 50 },
|
||||
[TRAINER_CLASS_POKEMANIAC] = { _("怪兽狂"), 15 },
|
||||
[TRAINER_CLASS_GUITARIST] = { _("吉他手"), 8 },
|
||||
@ -335,13 +335,13 @@ const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT] =
|
||||
[TRAINER_CLASS_PSYCHIC] = { _("超能力者"), 6 },
|
||||
[TRAINER_CLASS_GENTLEMAN] = { _("绅士"), 20, BALL_LUXURY },
|
||||
[TRAINER_CLASS_ELITE_FOUR] = { _("四天王"), 25, BALL_ULTRA },
|
||||
[TRAINER_CLASS_LEADER] = { _("道馆馆主"), 25 },
|
||||
[TRAINER_CLASS_LEADER] = { _("道馆馆主"), 25, B_TRAINER_CLASS_POKE_BALLS >= GEN_8 ? BALL_ULTRA : BALL_POKE },
|
||||
[TRAINER_CLASS_SCHOOL_KID] = { _("补习班学生") },
|
||||
[TRAINER_CLASS_SR_AND_JR] = { _("前辈和后辈"), 4 },
|
||||
[TRAINER_CLASS_WINSTRATE] = { _("连胜家族"), 10 },
|
||||
[TRAINER_CLASS_POKEFAN] = { _("发烧友俱乐部"), 20 },
|
||||
[TRAINER_CLASS_YOUNGSTER] = { _("短裤小子"), 4 },
|
||||
[TRAINER_CLASS_CHAMPION] = { _("冠军"), 50 },
|
||||
[TRAINER_CLASS_CHAMPION] = { _("冠军"), 50, BALL_ULTRA },
|
||||
[TRAINER_CLASS_FISHERMAN] = { _("垂钓者"), 10, B_TRAINER_CLASS_POKE_BALLS >= GEN_8 ? BALL_DIVE : BALL_LURE },
|
||||
[TRAINER_CLASS_TRIATHLETE] = { _("铁人三项选手"), 10 },
|
||||
[TRAINER_CLASS_DRAGON_TAMER] = { _("驯龙师"), 12 },
|
||||
@ -361,7 +361,7 @@ const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT] =
|
||||
[TRAINER_CLASS_YOUNG_COUPLE] = { _("热恋情侣"), 8 },
|
||||
[TRAINER_CLASS_OLD_COUPLE] = { _("金婚夫妻"), 10 },
|
||||
[TRAINER_CLASS_SIS_AND_BRO] = { _("海上姐弟"), 3 },
|
||||
[TRAINER_CLASS_SALON_MAIDEN] = { _("对战塔大君") },
|
||||
[TRAINER_CLASS_SALON_MAIDEN] = { _("对战塔大君"), 0, BALL_ULTRA },
|
||||
[TRAINER_CLASS_DOME_ACE] = { _("巨蛋超级巨星") },
|
||||
[TRAINER_CLASS_PALACE_MAVEN] = { _("宫殿守护者") },
|
||||
[TRAINER_CLASS_ARENA_TYCOON] = { _("竞技场主将") },
|
||||
|
||||
@ -7876,7 +7876,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case HOLD_EFFECT_LIGHT_BALL:
|
||||
if (atkBaseSpeciesId == SPECIES_PIKACHU && (B_LIGHT_BALL_ATTACK_BOOST >= GEN_4 || IsBattleMoveSpecial(move)))
|
||||
if (atkBaseSpeciesId == SPECIES_PIKACHU && (GetConfig(CONFIG_LIGHT_BALL_ATTACK_BOOST) >= GEN_4 || IsBattleMoveSpecial(move)))
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case HOLD_EFFECT_CHOICE_BAND:
|
||||
|
||||
@ -937,7 +937,7 @@ static void GetItemNameFromPocket(u8 *dest, u16 itemId)
|
||||
{
|
||||
case POCKET_TM_HM:
|
||||
end = StringCopy(gStringVar2, GetMoveName(ItemIdToBattleMoveId(itemId)));
|
||||
PrependFontIdToFit(gStringVar2, end, FONT_NARROW, 61);
|
||||
PrependFontIdToFit(gStringVar2, end, FONT_NARROW, NUM_TECHNICAL_MACHINES >= 100 ? 60 : 65);
|
||||
if (GetItemTMHMIndex(itemId) > NUM_TECHNICAL_MACHINES)
|
||||
{
|
||||
// Get HM number
|
||||
@ -947,7 +947,7 @@ static void GetItemNameFromPocket(u8 *dest, u16 itemId)
|
||||
else
|
||||
{
|
||||
// Get TM number
|
||||
ConvertIntToDecimalStringN(gStringVar1, GetItemTMHMIndex(itemId), STR_CONV_MODE_LEADING_ZEROS, 2);
|
||||
ConvertIntToDecimalStringN(gStringVar1, GetItemTMHMIndex(itemId), STR_CONV_MODE_LEADING_ZEROS, NUM_TECHNICAL_MACHINES >= 100 ? 3 : 2);
|
||||
StringExpandPlaceholders(dest, gText_NumberItem_TMBerry);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -237,7 +237,7 @@ static void CB2_ReshowBlankBattleScreenAfterMenu(void)
|
||||
gBattleScripting.reshowMainState--;
|
||||
break;
|
||||
case 10:
|
||||
if (gBattleScripting.monCaught)
|
||||
if (gBattleScripting.monCaught)
|
||||
CreateCaughtMonSprite(); // displays the caught mon for the switch into party feature
|
||||
break;
|
||||
default:
|
||||
@ -324,7 +324,7 @@ void CreateBattlerSprite(u32 battler)
|
||||
gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 0x50,
|
||||
(8 - gTrainerBacksprites[gSaveBlock2Ptr->playerGender].coordinates.size) * 4 + 80,
|
||||
GetBattlerSpriteSubpriority(0));
|
||||
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler;
|
||||
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = (8 + battler / 2);
|
||||
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCallbackDummy;
|
||||
gSprites[gBattlerSpriteIds[battler]].data[0] = battler;
|
||||
}
|
||||
@ -334,7 +334,7 @@ void CreateBattlerSprite(u32 battler)
|
||||
gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, 0x50,
|
||||
(8 - gTrainerBacksprites[TRAINER_BACK_PIC_WALLY].coordinates.size) * 4 + 80,
|
||||
GetBattlerSpriteSubpriority(0));
|
||||
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler;
|
||||
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = (8 + battler / 2);
|
||||
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCallbackDummy;
|
||||
gSprites[gBattlerSpriteIds[battler]].data[0] = battler;
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ const u8 *const gPocketNamesStringsTable[] =
|
||||
[POCKET_KEY_ITEMS] = COMPOUND_STRING("重要物品")
|
||||
};
|
||||
|
||||
const u8 gText_NumberItem_TMBerry[] = _("{NO}{STR_VAR_1}{CLEAR 0x07}{STR_VAR_2}");
|
||||
const u8 gText_NumberItem_TMBerry[] = _("{NO}{STR_VAR_1}{CLEAR 0x03}{STR_VAR_2}");
|
||||
const u8 gText_NumberItem_HM[] = _("{CLEAR_TO 0x11}{STR_VAR_1}{CLEAR 0x05}{STR_VAR_2}");
|
||||
|
||||
const u8 gText_ShopBuy[] = _("购买");
|
||||
|
||||
@ -689,10 +689,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,10 +777,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,10 +865,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -938,10 +953,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,10 +1041,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1104,10 +1129,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,10 +1217,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1270,10 +1305,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1354,10 +1394,15 @@ DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to
|
||||
HP_BAR(opponentRight, captureDamage: &damage1);
|
||||
}
|
||||
} THEN {
|
||||
if (IsMoveSheerForceBoosted(move))
|
||||
if (IsMoveSheerForceBoosted(move)) {
|
||||
if (!(damage1 > damage2))
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_GT(damage1, damage2);
|
||||
else
|
||||
} else {
|
||||
if (damage1 != damage2)
|
||||
DebugPrintf("Move that failed: %S", gMovesInfo[move].name);
|
||||
EXPECT_EQ(damage2, damage1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -796,6 +796,20 @@ AI_DOUBLE_BATTLE_TEST("AI uses Helping Hand if the ally does notably more damage
|
||||
}
|
||||
}
|
||||
|
||||
AI_DOUBLE_BATTLE_TEST("AI does not use Helping Hand on Good as Gold ally")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_HELPING_HAND) == EFFECT_HELPING_HAND);
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_DOUBLE_BATTLE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_CELEBRATE); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_HELPING_HAND, MOVE_MUD_SLAP); }
|
||||
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); Moves(MOVE_MUDDY_WATER); }
|
||||
} WHEN {
|
||||
TURN { EXPECT_MOVE(opponentLeft, MOVE_MUD_SLAP); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_DOUBLE_BATTLE_TEST("AI uses Tailwind")
|
||||
{
|
||||
u32 speed1, speed2, speed3, speed4;
|
||||
|
||||
@ -1,4 +1,99 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Light Ball (Hold Effect) test titles")
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetItemHoldEffect(ITEM_LIGHT_BALL) == HOLD_EFFECT_LIGHT_BALL);
|
||||
}
|
||||
|
||||
static const u32 speciesToCheck[] = {
|
||||
SPECIES_PICHU,
|
||||
SPECIES_PIKACHU,
|
||||
SPECIES_PIKACHU_COSPLAY,
|
||||
SPECIES_PIKACHU_ROCK_STAR,
|
||||
SPECIES_PIKACHU_BELLE,
|
||||
SPECIES_PIKACHU_POP_STAR,
|
||||
SPECIES_PIKACHU_PHD,
|
||||
SPECIES_PIKACHU_LIBRE,
|
||||
SPECIES_PIKACHU_ORIGINAL,
|
||||
SPECIES_PIKACHU_HOENN,
|
||||
SPECIES_PIKACHU_SINNOH,
|
||||
SPECIES_PIKACHU_UNOVA,
|
||||
SPECIES_PIKACHU_KALOS,
|
||||
SPECIES_PIKACHU_ALOLA,
|
||||
SPECIES_PIKACHU_PARTNER,
|
||||
SPECIES_PIKACHU_WORLD,
|
||||
SPECIES_PIKACHU_GMAX,
|
||||
};
|
||||
|
||||
SINGLE_BATTLE_TEST("Light Ball doubles Pikachu's Special Attack", s16 damage)
|
||||
{
|
||||
u32 species = 0, item = 0;
|
||||
|
||||
for (u32 j = 0; j < ARRAY_COUNT(speciesToCheck); j++) {
|
||||
PARAMETRIZE { item = ITEM_NONE; species = speciesToCheck[j]; }
|
||||
PARAMETRIZE { item = ITEM_LIGHT_BALL; species = speciesToCheck[j]; }
|
||||
}
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveCategory(MOVE_THUNDERSHOCK) == DAMAGE_CATEGORY_SPECIAL);
|
||||
if (species == SPECIES_PIKACHU_GMAX) {
|
||||
PLAYER(SPECIES_PIKACHU) { Item(item); GigantamaxFactor(TRUE); }
|
||||
} else {
|
||||
PLAYER(species) { Item(item); }
|
||||
}
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
if (species == SPECIES_PIKACHU_GMAX) {
|
||||
TURN { MOVE(player, MOVE_THUNDERSHOCK, gimmick: GIMMICK_DYNAMAX); }
|
||||
} else {
|
||||
TURN { MOVE(player, MOVE_THUNDERSHOCK); }
|
||||
}
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} THEN {
|
||||
if (i == 1) { // First check to avoid boosting other species
|
||||
EXPECT_EQ(results[i - 1].damage, results[i].damage);
|
||||
} else if (i % 2 == 1) { // Every 2nd test afterwards
|
||||
EXPECT_MUL_EQ(results[i - 1].damage, Q_4_12(2.0), results[i].damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Light Ball doubles Pikachu's Attack (Gen4+)", s16 damage)
|
||||
{
|
||||
u32 species = 0, item = 0, config = 0;
|
||||
|
||||
for (u32 j = 0; j < ARRAY_COUNT(speciesToCheck); j++) {
|
||||
PARAMETRIZE { item = ITEM_NONE; config = GEN_3; species = speciesToCheck[j]; }
|
||||
PARAMETRIZE { item = ITEM_LIGHT_BALL; config = GEN_3; species = speciesToCheck[j]; }
|
||||
PARAMETRIZE { item = ITEM_LIGHT_BALL; config = GEN_4; species = speciesToCheck[j]; }
|
||||
}
|
||||
|
||||
GIVEN {
|
||||
WITH_CONFIG(CONFIG_LIGHT_BALL_ATTACK_BOOST, config);
|
||||
ASSUME(GetMoveCategory(MOVE_SPARK) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
if (species == SPECIES_PIKACHU_GMAX) {
|
||||
PLAYER(SPECIES_PIKACHU) { Item(item); GigantamaxFactor(TRUE); }
|
||||
} else {
|
||||
PLAYER(species) { Item(item); }
|
||||
}
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
if (species == SPECIES_PIKACHU_GMAX) {
|
||||
TURN { MOVE(player, MOVE_SPARK, gimmick: GIMMICK_DYNAMAX); }
|
||||
} else {
|
||||
TURN { MOVE(player, MOVE_SPARK); }
|
||||
}
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} THEN {
|
||||
if (i == 2) { // First check to avoid boosting other species
|
||||
EXPECT_EQ(results[i - 2].damage, results[i].damage); // No item vs Light Ball
|
||||
EXPECT_EQ(results[i - 1].damage, results[i].damage); // Gen 3 vs Gen 4
|
||||
} else if (i % 3 == 2) { // Every 3rd test afterwards
|
||||
EXPECT_MUL_EQ(results[i - 2].damage, Q_4_12(2.0), results[i].damage); // No item vs Light Ball
|
||||
EXPECT_MUL_EQ(results[i - 1].damage, Q_4_12(2.0), results[i].damage); // Gen 3 vs Gen 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Acrobatics doubles in power if the user has no held item", s
|
||||
} SCENE {
|
||||
HP_BAR(player, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2), results[1].damage);
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faint
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]);
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2.0), damage[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faint
|
||||
HP_BAR(player, captureDamage: &damage[0]);
|
||||
HP_BAR(player, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]);
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2.0), damage[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ DOUBLE_BATTLE_TEST("Retaliate works with passive damage")
|
||||
HP_BAR(opponentRight, captureDamage: &damage[0]);
|
||||
HP_BAR(opponentRight, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]);
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2.0), damage[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ SINGLE_BATTLE_TEST("Retaliate works with Perish Song")
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]);
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2.0), damage[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +135,6 @@ SINGLE_BATTLE_TEST("Retaliate works with self-inflicted fainting")
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]);
|
||||
EXPECT_MUL_EQ(damage[1], Q_4_12(2.0), damage[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user