Add B_LEVEL_UP_NOTIFICATION to improve player QoL when performing multiple level ups (#4901)
Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
parent
1344d8e9dd
commit
e146940f25
@ -396,6 +396,7 @@ struct BattleCallbacksStack
|
||||
struct StatsArray
|
||||
{
|
||||
u16 stats[NUM_STATS];
|
||||
u16 level;
|
||||
};
|
||||
|
||||
struct BattleResources
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#define B_SPLIT_EXP GEN_LATEST // In Gen6+, all participating mon get full experience.
|
||||
#define B_SCALED_EXP GEN_LATEST // In Gen5 and Gen7+, experience is weighted by level difference.
|
||||
#define B_UNEVOLVED_EXP_MULTIPLIER GEN_LATEST // In Gen6+, if the Pokémon is at or past the level where it would be able to evolve, but it has not, it gets a ~1.2 multiplier to EXP gain. Only applies to Pokémon with EVO_LEVEL method.
|
||||
#define B_LEVEL_UP_NOTIFICATION GEN_LATEST // In Gen9+, if the Pokémon gets enough experience to level up multiple times, the message is only displayed once.
|
||||
|
||||
// Stat settings
|
||||
#define B_BADGE_BOOST GEN_LATEST // In Gen4+, Gym Badges no longer boost a Pokémon's stats.
|
||||
|
||||
@ -658,6 +658,7 @@ void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot);
|
||||
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot);
|
||||
void GiveMonInitialMoveset(struct Pokemon *mon);
|
||||
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
|
||||
u16 MonTryLearningNewMoveAtLevel(struct Pokemon *mon, bool32 firstMove, u32 level);
|
||||
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove);
|
||||
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move);
|
||||
void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
|
||||
|
||||
@ -1453,11 +1453,13 @@ 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 expAfterGain = currExp + gainedExp;
|
||||
u32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
|
||||
if (currExp + gainedExp >= nextLvlExp)
|
||||
if (expAfterGain >= nextLvlExp)
|
||||
{
|
||||
SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
|
||||
SetMonData(mon, MON_DATA_EXP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? &expAfterGain : &nextLvlExp);
|
||||
|
||||
CalculateMonStats(mon);
|
||||
|
||||
// Reapply Dynamax HP multiplier after stats are recalculated.
|
||||
@ -1465,7 +1467,7 @@ static void Task_GiveExpToMon(u8 taskId)
|
||||
DynamaxModifyHPLevelUp(mon, battler, oldMaxHP);
|
||||
|
||||
gainedExp -= nextLvlExp - currExp;
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp);
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? 0 : gainedExp);
|
||||
|
||||
if (IsDoubleBattle() == TRUE
|
||||
&& (monId == gBattlerPartyIndexes[battler] || monId == gBattlerPartyIndexes[BATTLE_PARTNER(battler)]))
|
||||
@ -1509,7 +1511,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
|
||||
|
||||
static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
{
|
||||
u8 level;
|
||||
u32 level, expAfterGain;
|
||||
u16 species;
|
||||
u32 oldMaxHP;
|
||||
s32 currExp, expOnNextLvl, newExpPoints;
|
||||
@ -1536,9 +1538,14 @@ static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP);
|
||||
expOnNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1];
|
||||
|
||||
if (currExp + gainedExp >= expOnNextLvl)
|
||||
expAfterGain = currExp + gainedExp;
|
||||
if (expAfterGain >= expOnNextLvl)
|
||||
{
|
||||
SetMonData(mon, MON_DATA_EXP, &expOnNextLvl);
|
||||
if (B_LEVEL_UP_NOTIFICATION >= GEN_9)
|
||||
SetMonData(mon, MON_DATA_EXP, &expAfterGain);
|
||||
else
|
||||
SetMonData(mon, MON_DATA_EXP, &expOnNextLvl);
|
||||
|
||||
CalculateMonStats(mon);
|
||||
|
||||
// Reapply Dynamax HP multiplier after stats are recalculated.
|
||||
@ -1546,7 +1553,7 @@ static void Task_GiveExpWithExpBar(u8 taskId)
|
||||
DynamaxModifyHPLevelUp(mon, battler, oldMaxHP);
|
||||
|
||||
gainedExp -= expOnNextLvl - currExp;
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp);
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? 0 : gainedExp);
|
||||
gTasks[taskId].func = Task_LaunchLvlUpAnim;
|
||||
}
|
||||
else
|
||||
|
||||
@ -5100,6 +5100,7 @@ static void Cmd_getexp(void)
|
||||
u32 holdEffect;
|
||||
s32 i; // also used as stringId
|
||||
u8 *expMonId = &gBattleStruct->expGetterMonId;
|
||||
u32 currLvl;
|
||||
|
||||
gBattlerFainted = GetBattlerForBattleScript(cmd->battler);
|
||||
|
||||
@ -5314,7 +5315,8 @@ static void Cmd_getexp(void)
|
||||
if (gBattleControllerExecFlags == 0)
|
||||
{
|
||||
gBattleResources->bufferB[gBattleStruct->expGetterBattlerId][0] = 0;
|
||||
if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_HP) && GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) != MAX_LEVEL)
|
||||
currLvl = GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL);
|
||||
if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_HP) && currLvl != MAX_LEVEL)
|
||||
{
|
||||
gBattleResources->beforeLvlUp->stats[STAT_HP] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_MAX_HP);
|
||||
gBattleResources->beforeLvlUp->stats[STAT_ATK] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_ATK);
|
||||
@ -5322,6 +5324,7 @@ static void Cmd_getexp(void)
|
||||
gBattleResources->beforeLvlUp->stats[STAT_SPEED] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPEED);
|
||||
gBattleResources->beforeLvlUp->stats[STAT_SPATK] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPATK);
|
||||
gBattleResources->beforeLvlUp->stats[STAT_SPDEF] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPDEF);
|
||||
gBattleResources->beforeLvlUp->level = currLvl;
|
||||
|
||||
BtlController_EmitExpUpdate(gBattleStruct->expGetterBattlerId, BUFFER_A, *expMonId, gBattleStruct->battlerExpReward);
|
||||
MarkBattlerForControllerExec(gBattleStruct->expGetterBattlerId);
|
||||
@ -8643,10 +8646,32 @@ static void Cmd_handlelearnnewmove(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *learnedMovePtr, const u8 *nothingToLearnPtr, bool8 isFirstMove);
|
||||
|
||||
u16 learnMove = MOVE_NONE;
|
||||
u32 monId = gBattleStruct->expGetterMonId;
|
||||
u16 learnMove = MonTryLearningNewMove(&gPlayerParty[monId], cmd->isFirstMove);
|
||||
while (learnMove == MON_ALREADY_KNOWS_MOVE)
|
||||
learnMove = MonTryLearningNewMove(&gPlayerParty[monId], FALSE);
|
||||
|
||||
if (B_LEVEL_UP_NOTIFICATION >= GEN_9)
|
||||
{
|
||||
u32 currLvl = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL);
|
||||
|
||||
while (gBattleResources->beforeLvlUp->level <= currLvl)
|
||||
{
|
||||
learnMove = MonTryLearningNewMoveAtLevel(&gPlayerParty[monId], cmd->isFirstMove, gBattleResources->beforeLvlUp->level);
|
||||
|
||||
while (learnMove == MON_ALREADY_KNOWS_MOVE)
|
||||
learnMove = MonTryLearningNewMoveAtLevel(&gPlayerParty[monId], FALSE, gBattleResources->beforeLvlUp->level);
|
||||
|
||||
if (learnMove != MOVE_NONE)
|
||||
break;
|
||||
|
||||
gBattleResources->beforeLvlUp->level++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
learnMove = MonTryLearningNewMove(&gPlayerParty[monId], cmd->isFirstMove);
|
||||
while (learnMove == MON_ALREADY_KNOWS_MOVE)
|
||||
learnMove = MonTryLearningNewMove(&gPlayerParty[monId], FALSE);
|
||||
}
|
||||
|
||||
if (learnMove == MOVE_NONE || RECORDED_WILD_BATTLE)
|
||||
{
|
||||
|
||||
@ -1982,11 +1982,10 @@ void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) //Credit: AsparagusEdua
|
||||
}
|
||||
}
|
||||
|
||||
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
|
||||
u16 MonTryLearningNewMoveAtLevel(struct Pokemon *mon, bool32 firstMove, u32 level)
|
||||
{
|
||||
u32 retVal = MOVE_NONE;
|
||||
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
|
||||
const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species);
|
||||
|
||||
// since you can learn more than one move per level
|
||||
@ -2034,6 +2033,11 @@ u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
|
||||
{
|
||||
return MonTryLearningNewMoveAtLevel(mon, firstMove, GetMonData(mon, MON_DATA_LEVEL, NULL));
|
||||
}
|
||||
|
||||
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user