Fixes various Dynamax HP conversions/calculations (#5933)
This commit is contained in:
parent
5a0c5480b2
commit
c10287b4c1
@ -589,7 +589,6 @@ struct DynamaxData
|
||||
u8 dynamaxTurns[MAX_BATTLERS_COUNT];
|
||||
u16 baseMoves[MAX_BATTLERS_COUNT]; // base move of Max Move
|
||||
u16 lastUsedBaseMove;
|
||||
u16 levelUpHP;
|
||||
};
|
||||
|
||||
struct BattleGimmickData
|
||||
|
||||
@ -58,7 +58,7 @@ enum MaxMoveEffect
|
||||
|
||||
bool32 CanDynamax(u32 battler);
|
||||
bool32 IsGigantamaxed(u32 battler);
|
||||
void ApplyDynamaxHPMultiplier(u32 battler, struct Pokemon* mon);
|
||||
void ApplyDynamaxHPMultiplier(struct Pokemon* mon);
|
||||
void ActivateDynamax(u32 battler);
|
||||
u16 GetNonDynamaxHP(u32 battler);
|
||||
u16 GetNonDynamaxMaxHP(u32 battler);
|
||||
|
||||
@ -286,7 +286,7 @@ u32 GetBattlerMoveTargetType(u32 battler, u32 move);
|
||||
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move);
|
||||
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing);
|
||||
bool32 IsAlly(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 IsGen6ExpShareEnabled(void);
|
||||
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
|
||||
|
||||
@ -910,5 +910,6 @@ const u8 *GetMoveAnimationScript(u16 moveId);
|
||||
void UpdateDaysPassedSinceFormChange(u16 days);
|
||||
void TrySetDayLimitToFormChange(struct Pokemon *mon);
|
||||
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler);
|
||||
uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier);
|
||||
|
||||
#endif // GUARD_POKEMON_H
|
||||
|
||||
@ -1410,6 +1410,14 @@ void Task_PlayerController_RestoreBgmAfterCry(u8 taskId)
|
||||
#define tExpTask_gainedExp_2 data[4] // Stored as two half-words containing a word.
|
||||
#define tExpTask_frames data[10]
|
||||
|
||||
static void DynamaxModifyHPLevelUp(struct Pokemon *mon, u32 battler, u32 oldMaxHP)
|
||||
{
|
||||
ApplyDynamaxHPMultiplier(mon);
|
||||
gBattleScripting.levelUpHP = GetMonData(mon, MON_DATA_MAX_HP) - oldMaxHP; // overwrite levelUpHP since it overflows
|
||||
gBattleMons[battler].hp += gBattleScripting.levelUpHP;
|
||||
SetMonData(mon, MON_DATA_HP, &gBattleMons[battler].hp);
|
||||
}
|
||||
|
||||
static s32 GetTaskExpValue(u8 taskId)
|
||||
{
|
||||
return (u16)(gTasks[taskId].tExpTask_gainedExp_1) | (gTasks[taskId].tExpTask_gainedExp_2 << 16);
|
||||
@ -1428,21 +1436,16 @@ static void Task_GiveExpToMon(u8 taskId)
|
||||
u8 level = GetMonData(mon, MON_DATA_LEVEL);
|
||||
u32 currExp = GetMonData(mon, MON_DATA_EXP);
|
||||
u32 nextLvlExp = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1];
|
||||
u32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
|
||||
if (currExp + gainedExp >= nextLvlExp)
|
||||
{
|
||||
SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
|
||||
gBattleStruct->dynamax.levelUpHP = GetMonData(mon, MON_DATA_HP) \
|
||||
+ UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND);
|
||||
CalculateMonStats(mon);
|
||||
|
||||
// Reapply Dynamax HP multiplier after stats are recalculated.
|
||||
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && monId == gBattlerPartyIndexes[battler])
|
||||
{
|
||||
ApplyDynamaxHPMultiplier(battler, mon);
|
||||
gBattleMons[battler].hp = gBattleStruct->dynamax.levelUpHP;
|
||||
SetMonData(mon, MON_DATA_HP, &gBattleMons[battler].hp);
|
||||
}
|
||||
DynamaxModifyHPLevelUp(mon, battler, oldMaxHP);
|
||||
|
||||
gainedExp -= nextLvlExp - currExp;
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp);
|
||||
@ -1491,6 +1494,7 @@ static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
{
|
||||
u8 level;
|
||||
u16 species;
|
||||
u32 oldMaxHP;
|
||||
s32 currExp, expOnNextLvl, newExpPoints;
|
||||
|
||||
if (gTasks[taskId].tExpTask_frames < 13)
|
||||
@ -1502,31 +1506,27 @@ static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
u8 monId = gTasks[taskId].tExpTask_monId;
|
||||
s32 gainedExp = GetTaskExpValue(taskId);
|
||||
u8 battler = gTasks[taskId].tExpTask_battler;
|
||||
struct Pokemon *mon = &gPlayerParty[monId];
|
||||
|
||||
newExpPoints = MoveBattleBar(battler, gHealthboxSpriteIds[battler], EXP_BAR, 0);
|
||||
SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
|
||||
if (newExpPoints == -1) // The bar has been filled with given exp points.
|
||||
{
|
||||
m4aSongNumStop(SE_EXP);
|
||||
level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL);
|
||||
currExp = GetMonData(&gPlayerParty[monId], MON_DATA_EXP);
|
||||
species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES);
|
||||
level = GetMonData(mon, MON_DATA_LEVEL);
|
||||
currExp = GetMonData(mon, MON_DATA_EXP);
|
||||
species = GetMonData(mon, MON_DATA_SPECIES);
|
||||
oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
expOnNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1];
|
||||
|
||||
if (currExp + gainedExp >= expOnNextLvl)
|
||||
{
|
||||
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl);
|
||||
gBattleStruct->dynamax.levelUpHP = GetMonData(&gPlayerParty[monId], MON_DATA_HP) \
|
||||
+ UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND);
|
||||
CalculateMonStats(&gPlayerParty[monId]);
|
||||
SetMonData(mon, MON_DATA_EXP, &expOnNextLvl);
|
||||
CalculateMonStats(mon);
|
||||
|
||||
// Reapply Dynamax HP multiplier after stats are recalculated.
|
||||
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && monId == gBattlerPartyIndexes[battler])
|
||||
{
|
||||
ApplyDynamaxHPMultiplier(battler, &gPlayerParty[monId]);
|
||||
gBattleMons[battler].hp = gBattleStruct->dynamax.levelUpHP;
|
||||
SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleMons[battler].hp);
|
||||
}
|
||||
DynamaxModifyHPLevelUp(mon, battler, oldMaxHP);
|
||||
|
||||
gainedExp -= expOnNextLvl - currExp;
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp);
|
||||
@ -1535,7 +1535,7 @@ static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
else
|
||||
{
|
||||
currExp += gainedExp;
|
||||
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp);
|
||||
SetMonData(mon, MON_DATA_EXP, &currExp);
|
||||
gBattlerControllerFuncs[battler] = Controller_WaitForString;
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
|
||||
@ -123,22 +123,22 @@ bool32 CanDynamax(u32 battler)
|
||||
// Returns whether a battler is transformed into a Gigantamax form.
|
||||
bool32 IsGigantamaxed(u32 battler)
|
||||
{
|
||||
struct Pokemon *mon = &GetSideParty(GetBattlerSide(battler))[gBattlerPartyIndexes[battler]];
|
||||
struct Pokemon *mon = GetPartyBattlerData(battler);
|
||||
if ((gSpeciesInfo[gBattleMons[battler].species].isGigantamax) && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Applies the HP Multiplier for Dynamaxed Pokemon and Raid Bosses.
|
||||
void ApplyDynamaxHPMultiplier(u32 battler, struct Pokemon* mon)
|
||||
void ApplyDynamaxHPMultiplier(struct Pokemon* mon)
|
||||
{
|
||||
if (GetMonData(mon, MON_DATA_SPECIES) == SPECIES_SHEDINJA)
|
||||
return;
|
||||
else
|
||||
{
|
||||
u32 scale = 150 + 5 * GetMonData(mon, MON_DATA_DYNAMAX_LEVEL);
|
||||
u32 hp = (GetMonData(mon, MON_DATA_HP) * scale + 99) / 100;
|
||||
u32 maxHP = (GetMonData(mon, MON_DATA_MAX_HP) * scale + 99) / 100;
|
||||
uq4_12_t multiplier = GetDynamaxLevelHPMultiplier(GetMonData(mon, MON_DATA_DYNAMAX_LEVEL), FALSE);
|
||||
u32 hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * multiplier) + UQ_4_12_ROUND);
|
||||
u32 maxHP = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_MAX_HP) * multiplier) + UQ_4_12_ROUND);
|
||||
SetMonData(mon, MON_DATA_HP, &hp);
|
||||
SetMonData(mon, MON_DATA_MAX_HP, &maxHP);
|
||||
}
|
||||
@ -151,8 +151,9 @@ u16 GetNonDynamaxHP(u32 battler)
|
||||
return gBattleMons[battler].hp;
|
||||
else
|
||||
{
|
||||
u16 mult = UQ_4_12(1.0/1.5); // placeholder
|
||||
u16 hp = UQ_4_12_TO_INT((gBattleMons[battler].hp * mult) + UQ_4_12_ROUND);
|
||||
struct Pokemon *mon = GetPartyBattlerData(battler);
|
||||
uq4_12_t mult = GetDynamaxLevelHPMultiplier(GetMonData(mon, MON_DATA_DYNAMAX_LEVEL), TRUE);
|
||||
u32 hp = UQ_4_12_TO_INT((gBattleMons[battler].hp * mult) + UQ_4_12_ROUND);
|
||||
return hp;
|
||||
}
|
||||
}
|
||||
@ -164,8 +165,9 @@ u16 GetNonDynamaxMaxHP(u32 battler)
|
||||
return gBattleMons[battler].maxHP;
|
||||
else
|
||||
{
|
||||
u16 mult = UQ_4_12(1.0/1.5); // placeholder
|
||||
u16 maxHP = UQ_4_12_TO_INT((gBattleMons[battler].maxHP * mult) + UQ_4_12_ROUND);
|
||||
struct Pokemon *mon = GetPartyBattlerData(battler);
|
||||
uq4_12_t mult = GetDynamaxLevelHPMultiplier(GetMonData(mon, MON_DATA_DYNAMAX_LEVEL), TRUE);
|
||||
u32 maxHP = UQ_4_12_TO_INT((gBattleMons[battler].maxHP * mult) + UQ_4_12_ROUND);
|
||||
return maxHP;
|
||||
}
|
||||
}
|
||||
@ -202,7 +204,7 @@ void UndoDynamax(u32 battler)
|
||||
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX)
|
||||
{
|
||||
struct Pokemon *mon = (side == B_SIDE_PLAYER) ? &gPlayerParty[monId] : &gEnemyParty[monId];
|
||||
u16 mult = UQ_4_12(1.0/1.5); // placeholder
|
||||
uq4_12_t mult = GetDynamaxLevelHPMultiplier(GetMonData(mon, MON_DATA_DYNAMAX_LEVEL), TRUE);
|
||||
gBattleMons[battler].hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult + 1) + UQ_4_12_ROUND); // round up
|
||||
SetMonData(mon, MON_DATA_HP, &gBattleMons[battler].hp);
|
||||
CalculateMonStats(mon);
|
||||
@ -508,10 +510,10 @@ void BS_UpdateDynamax(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
u32 battler = gBattleScripting.battler;
|
||||
struct Pokemon *mon = &GetSideParty(GetBattlerSide(battler))[gBattlerPartyIndexes[battler]];
|
||||
struct Pokemon *mon = GetPartyBattlerData(battler);
|
||||
|
||||
if (!IsGigantamaxed(battler)) // RecalcBattlerStats will get called on form change.
|
||||
RecalcBattlerStats(battler, mon);
|
||||
RecalcBattlerStats(battler, mon, GetActiveGimmick(battler) == GIMMICK_DYNAMAX);
|
||||
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
@ -10157,7 +10157,7 @@ static void Cmd_various(void)
|
||||
// Change stats.
|
||||
else if (cmd->case_ == 1)
|
||||
{
|
||||
RecalcBattlerStats(battler, mon);
|
||||
RecalcBattlerStats(battler, mon, FALSE);
|
||||
}
|
||||
// Update healthbox.
|
||||
else
|
||||
|
||||
@ -11083,7 +11083,7 @@ bool32 TryBattleFormChange(u32 battler, u32 method)
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
|
||||
gBattleMons[battler].species = targetSpecies;
|
||||
RecalcBattlerStats(battler, &party[monId]);
|
||||
RecalcBattlerStats(battler, &party[monId], method == FORM_CHANGE_BATTLE_GIGANTAMAX);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gBattleStruct->changedSpecies[side][monId] != SPECIES_NONE)
|
||||
@ -11108,7 +11108,7 @@ bool32 TryBattleFormChange(u32 battler, u32 method)
|
||||
// Reverts the original species
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[side][monId]);
|
||||
RecalcBattlerStats(battler, &party[monId]);
|
||||
RecalcBattlerStats(battler, &party[monId], method == FORM_CHANGE_BATTLE_GIGANTAMAX);
|
||||
// Battler data is not updated with regular form's ability, not doing so could cause wrong ability activation.
|
||||
if (method == FORM_CHANGE_FAINT)
|
||||
gBattleMons[battler].ability = abilityForm;
|
||||
@ -11696,11 +11696,28 @@ void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon)
|
||||
gBattleMons[battler].types[2] = TYPE_MYSTERY;
|
||||
}
|
||||
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon)
|
||||
void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing)
|
||||
{
|
||||
u32 hp = GetMonData(mon, MON_DATA_HP);
|
||||
u32 oldMaxHp = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
CalculateMonStats(mon);
|
||||
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && gChosenActionByBattler[battler] != B_ACTION_SWITCH)
|
||||
ApplyDynamaxHPMultiplier(battler, mon);
|
||||
{
|
||||
ApplyDynamaxHPMultiplier(mon);
|
||||
u32 newMaxHp = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
if (!isDynamaxing)
|
||||
{
|
||||
if (newMaxHp > oldMaxHp) // restore hp gained from changing form, without this, dynamaxed form changes are calculated incorrectly
|
||||
{
|
||||
hp += (newMaxHp - oldMaxHp);
|
||||
SetMonData(mon, MON_DATA_HP, &hp);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMonData(mon, MON_DATA_HP, &hp);
|
||||
}
|
||||
}
|
||||
}
|
||||
CopyMonLevelAndBaseStatsToBattleMon(battler, mon);
|
||||
CopyMonAbilityAndTypesToBattleMon(battler, mon);
|
||||
}
|
||||
|
||||
@ -6978,3 +6978,10 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
|
||||
return moveType;
|
||||
return gMovesInfo[move].type;
|
||||
}
|
||||
|
||||
uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier)
|
||||
{
|
||||
if (inverseMultiplier)
|
||||
return UQ_4_12(1.0/(1.5 + 0.05 * dynamaxLevel));
|
||||
return UQ_4_12(1.5 + 0.05 * dynamaxLevel);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x", u16 hp)
|
||||
u32 dynamax;
|
||||
PARAMETRIZE { dynamax = GIMMICK_NONE; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
|
||||
GIVEN { // TODO: Dynamax level
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
@ -25,6 +25,49 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax increases HP and max HP by 1.5x", u16 hp)
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax Level increases HP and max HP multipliers by 0.05 for each level", u16 hp)
|
||||
{
|
||||
u32 dynamax, level;
|
||||
PARAMETRIZE { dynamax = GIMMICK_NONE; level = 0; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 0; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 1; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 2; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 3; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 4; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 5; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 6; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 7; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 8; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 9; }
|
||||
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; level = 10; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { DynamaxLevel(level); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
if (dynamax) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_DYNAMAX_GROWTH, player);
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
}
|
||||
MESSAGE("The opposing Wobbuffet used Celebrate!");
|
||||
} THEN {
|
||||
results[i].hp = player->hp;
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.5), results[1].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.55), results[2].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.6), results[3].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.65), results[4].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.7), results[5].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.75), results[6].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.8), results[7].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.85), results[8].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.9), results[9].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(1.95), results[10].hp);
|
||||
EXPECT_MUL_EQ(results[0].hp, Q_4_12(2.0), results[11].hp);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp)
|
||||
{
|
||||
u32 dynamax;
|
||||
@ -38,8 +81,8 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp)
|
||||
TURN { MOVE(player, MOVE_TACKLE); } // 2nd max move
|
||||
TURN { MOVE(player, MOVE_TACKLE); } // 3rd max move
|
||||
} SCENE {
|
||||
int i;
|
||||
for (i = 0; i < DYNAMAX_TURNS_COUNT; ++i) {
|
||||
int j;
|
||||
for (j = 0; j < DYNAMAX_TURNS_COUNT; ++j) {
|
||||
if (dynamax)
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
else
|
||||
@ -55,6 +98,49 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp)
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns and correctly converts HP according to Dynamax Level")
|
||||
{
|
||||
u32 dynamaxLevel, dynamax;
|
||||
u16 capturedHP, finalHP;
|
||||
s16 capturedDamage;
|
||||
PARAMETRIZE { dynamaxLevel = 0; dynamax = GIMMICK_NONE; }
|
||||
PARAMETRIZE { dynamaxLevel = 0; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 1; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 2; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 3; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 4; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 5; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 6; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 7; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 8; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 9; dynamax = GIMMICK_DYNAMAX; }
|
||||
PARAMETRIZE { dynamaxLevel = 10; dynamax = GIMMICK_DYNAMAX; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { DynamaxLevel(dynamaxLevel); HP(200); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_CELEBRATE, gimmick: dynamax); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_TACKLE); }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
if (dynamax)
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_DYNAMAX_GROWTH, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
if (dynamax)
|
||||
HP_BAR(player, captureHP: &capturedHP);
|
||||
else
|
||||
HP_BAR(player, captureDamage: &capturedDamage);
|
||||
if (dynamax)
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||
} THEN {
|
||||
finalHP = player->hp;
|
||||
if (dynamax)
|
||||
EXPECT_MUL_EQ(finalHP, GetDynamaxLevelHPMultiplier(dynamaxLevel, FALSE), capturedHP);
|
||||
EXPECT_LE(finalHP, 200);
|
||||
EXPECT_GE(finalHP, 200 - capturedDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched")
|
||||
{
|
||||
GIVEN {
|
||||
@ -311,6 +397,47 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain HP")
|
||||
{
|
||||
u16 capturedHP, finalHP;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GRENINJA_BATTLE_BOND) { Ability(ABILITY_BATTLE_BOND); HP(100); Speed(100); }
|
||||
OPPONENT(SPECIES_CATERPIE) { HP(1); Speed(1000); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(10); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_DYNAMAX_GROWTH, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
HP_BAR(player, captureHP: &capturedHP);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_STRIKE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||
} THEN {
|
||||
finalHP = player->hp;
|
||||
EXPECT_EQ(capturedHP, finalHP);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon that changes forms does not gain HP unless the new form gains Max HP")
|
||||
{
|
||||
u32 hp = 1, maxHP = 200;
|
||||
u32 species;
|
||||
PARAMETRIZE { species = SPECIES_ZYGARDE_10_POWER_CONSTRUCT; }
|
||||
PARAMETRIZE { species = SPECIES_ZYGARDE_50_POWER_CONSTRUCT; }
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_POWER_CONSTRUCT); HP(hp); MaxHP(maxHP); DynamaxLevel(0); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_DYNAMAX_GROWTH, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_STRIKE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(maxHP - hp, GetDynamaxLevelHPMultiplier(0, FALSE), player->maxHP - player->hp);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 damage)
|
||||
{
|
||||
bool32 protected;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user