Allow larger exp gains

This commit is contained in:
DizzyEggg 2021-06-03 23:17:44 +02:00
parent b7f9009c1e
commit 4b744374c8
5 changed files with 58 additions and 44 deletions

View File

@ -489,7 +489,7 @@ struct BattleStruct
u8 switchInAbilitiesCounter;
u8 faintedActionsState;
u8 faintedActionsBattlerId;
u16 expValue;
u32 expValue;
u8 field_52;
u8 sentInPokes;
bool8 selectionScriptFinished[MAX_BATTLERS_COUNT];

View File

@ -214,7 +214,7 @@ void BtlController_EmitChooseItem(u8 bufferId, u8* arg1);
void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u16 abilityId, u8* arg4);
void BtlController_EmitCmd23(u8 bufferId); // unused
void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue);
void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints);
void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, s32 expPoints);
void BtlController_EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2);
void BtlController_EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status);
void BtlController_EmitStatusXor(u8 bufferId, u8 b); // unused
@ -222,7 +222,7 @@ void BtlController_EmitDataTransfer(u8 bufferId, u16 size, void *data);
void BtlController_EmitDMA3Transfer(u8 bufferId, void *dst, u16 size, void *data); // unused
void BtlController_EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter); // unused
void BtlController_EmitCmd32(u8 bufferId, u16 size, void *c); // unused
void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u16 arg2);
void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u32 arg2);
void BtlController_EmitChosenMonReturnValue(u8 bufferId, u8 b, u8 *c);
void BtlController_EmitOneReturnValue(u8 bufferId, u16 arg1);
void BtlController_EmitOneReturnValue_Duplicate(u8 bufferId, u16 b);

View File

@ -1079,7 +1079,7 @@ static void Intro_TryShinyAnimShowHealthbox(void)
bool32 battlerAnimsDone = FALSE;
// Start shiny animation if applicable for 1st pokemon
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive)
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]);
@ -1089,7 +1089,7 @@ static void Intro_TryShinyAnimShowHealthbox(void)
TryShinyAnimation(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]);
// Show healthbox after ball anim
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive)
{
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted)
@ -1166,7 +1166,7 @@ static void SwitchIn_CleanShinyAnimShowSubstitute(void)
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
{
CopyBattleSpriteInvisibility(gActiveBattler);
// Reset shiny anim (even if it didn't occur)
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE;
@ -1243,16 +1243,22 @@ static void CompleteOnInactiveTextPrinter(void)
PlayerBufferExecCompleted();
}
#define tExpTask_monId data[0]
#define tExpTask_gainedExp data[1]
#define tExpTask_battler data[2]
#define tExpTask_frames data[10]
#define tExpTask_monId data[0]
#define tExpTask_battler data[2]
#define tExpTask_gainedExp_1 data[3]
#define tExpTask_gainedExp_2 data[4] // Stored as two half-words containing a word.
#define tExpTask_frames data[10]
static s32 GetTaskExpValue(u8 taskId)
{
return (u16)(gTasks[taskId].tExpTask_gainedExp_1) | (gTasks[taskId].tExpTask_gainedExp_2 << 16);
}
static void Task_GiveExpToMon(u8 taskId)
{
u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
u8 battlerId = gTasks[taskId].tExpTask_battler;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
s32 gainedExp = GetTaskExpValue(taskId);
if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battlerId]) // Give exp without moving the expbar.
{
@ -1297,7 +1303,7 @@ static void Task_GiveExpToMon(u8 taskId)
static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
s32 gainedExp = gTasks[taskId].tExpTask_gainedExp;
s32 gainedExp = GetTaskExpValue(taskId);
u8 battlerId = gTasks[taskId].tExpTask_battler;
struct Pokemon *mon = &gPlayerParty[monIndex];
u8 level = GetMonData(mon, MON_DATA_LEVEL);
@ -1322,9 +1328,9 @@ static void Task_GiveExpWithExpBar(u8 taskId)
else
{
u8 monId = gTasks[taskId].tExpTask_monId;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
s32 gainedExp = GetTaskExpValue(taskId);
u8 battlerId = gTasks[taskId].tExpTask_battler;
s16 newExpPoints;
s32 newExpPoints;
newExpPoints = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]);
@ -2833,6 +2839,7 @@ static void PlayerHandleHealthBarUpdate(void)
static void PlayerHandleExpUpdate(void)
{
u8 monId = gBattleResources->bufferA[gActiveBattler][1];
s32 taskId, expPointsToGive;
if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL)
{
@ -2840,23 +2847,22 @@ static void PlayerHandleExpUpdate(void)
}
else
{
s16 expPointsToGive;
u8 taskId;
LoadBattleBarGfx(1);
GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); // Unused return value.
expPointsToGive = T1_READ_16(&gBattleResources->bufferA[gActiveBattler][2]);
expPointsToGive = T1_READ_32(&gBattleResources->bufferA[gActiveBattler][2]);
taskId = CreateTask(Task_GiveExpToMon, 10);
gTasks[taskId].tExpTask_monId = monId;
gTasks[taskId].tExpTask_gainedExp = expPointsToGive;
gTasks[taskId].tExpTask_gainedExp_1 = expPointsToGive;
gTasks[taskId].tExpTask_gainedExp_2 = expPointsToGive >> 16;
gTasks[taskId].tExpTask_battler = gActiveBattler;
gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy;
}
}
#undef tExpTask_monId
#undef tExpTask_gainedExp
#undef tExpTask_battler
#undef tExpTask_gainedExp_1
#undef tExpTask_gainedExp_2
#undef tExpTask_frames
static void PlayerHandleStatusIconUpdate(void)

View File

@ -1220,14 +1220,15 @@ void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue)
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
// why is the argument u16 if it's being cast to s16 anyway?
void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints)
void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, s32 expPoints)
{
sBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE;
sBattleBuffersTransferData[1] = partyId;
sBattleBuffersTransferData[2] = (s16)expPoints;
sBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8;
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
sBattleBuffersTransferData[2] = expPoints;
sBattleBuffersTransferData[3] = (expPoints & 0x0000FF00) >> 8;
sBattleBuffersTransferData[4] = (expPoints & 0x00FF0000) >> 16;
sBattleBuffersTransferData[5] = (expPoints & 0xFF000000) >> 24;
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 6);
}
void BtlController_EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2)
@ -1315,13 +1316,15 @@ void BtlController_EmitCmd32(u8 bufferId, u16 size, void *data)
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 3);
}
void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u16 arg2)
void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u32 arg2)
{
sBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES;
sBattleBuffersTransferData[1] = arg1;
sBattleBuffersTransferData[2] = arg2;
sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8;
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
sBattleBuffersTransferData[3] = (arg2 & 0x0000FF00) >> 8;
sBattleBuffersTransferData[4] = (arg2 & 0x00FF0000) >> 16;
sBattleBuffersTransferData[5] = (arg2 & 0xFF000000) >> 24;
PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 6);
}
void BtlController_EmitChosenMonReturnValue(u8 bufferId, u8 partyId, u8 *battlePartyOrder)

View File

@ -1633,7 +1633,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move)
calc = (calc * (100 + atkParam)) / 100;
else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef));
calc = (calc * (100 + atkParam)) / 100;
if (gProtectStructs[battlerAtk].micle)
{
gProtectStructs[battlerAtk].micle = FALSE;
@ -3687,7 +3687,7 @@ static void Cmd_getexp(void)
u8 holdEffect;
s32 sentIn;
s32 viaExpShare = 0;
u16 *exp = &gBattleStruct->expValue;
u32 *exp = &gBattleStruct->expValue;
gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1];
@ -3714,7 +3714,7 @@ static void Cmd_getexp(void)
break;
case 1: // calculate experience points to redistribute
{
u16 calculatedExp;
u32 calculatedExp;
s32 viaSentIn;
for (viaSentIn = 0, i = 0; i < PARTY_SIZE; i++)
@ -3821,9 +3821,14 @@ static void Cmd_getexp(void)
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && B_TRAINER_EXP_MULTIPLIER <= GEN_7)
gBattleMoveDamage = (gBattleMoveDamage * 150) / 100;
#if (B_SCALED_EXP >= GEN_5) && (B_SCALED_EXP != GEN_6)
gBattleMoveDamage *= sExperienceScalingFactors[(gBattleMons[gBattlerFainted].level * 2) + 10];
gBattleMoveDamage /= sExperienceScalingFactors[gBattleMons[gBattlerFainted].level + GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) + 10];
gBattleMoveDamage++;
{
// Note: There is an edge case where if a pokemon receives a large amount of exp, it wouldn't be properly calculated
// because of multiplying by scaling factor(the value would simply be larger than an u32 can hold). Hence u64 is needed.
u64 value = gBattleMoveDamage;
value *= sExperienceScalingFactors[(gBattleMons[gBattlerFainted].level * 2) + 10];
value /= sExperienceScalingFactors[gBattleMons[gBattlerFainted].level + GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) + 10];
gBattleMoveDamage = value + 1;
}
#endif
if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId]))
@ -3865,7 +3870,7 @@ static void Cmd_getexp(void)
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, gBattleStruct->expGetterMonId);
// buffer 'gained' or 'gained a boosted'
PREPARE_STRING_BUFFER(gBattleTextBuff2, i);
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage);
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 6, gBattleMoveDamage);
PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBattlerId);
MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species);
@ -3911,7 +3916,7 @@ static void Cmd_getexp(void)
BattleScriptPushCursor();
gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterMonId];
gBattlescriptCurrInstr = BattleScript_LevelUp;
gBattleMoveDamage = (gBattleResources->bufferB[gActiveBattler][2] | (gBattleResources->bufferB[gActiveBattler][3] << 8));
gBattleMoveDamage = T1_READ_32(&gBattleResources->bufferB[gActiveBattler][2]);
AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterMonId], FRIENDSHIP_EVENT_GROW_LEVEL);
// update battle mon structure after level up
@ -4485,7 +4490,7 @@ static void Cmd_playanimation(void)
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
#if B_TERRAIN_BG_CHANGE == FALSE
if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG)
{
@ -7777,7 +7782,7 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
return;
}
if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
@ -9184,17 +9189,17 @@ bool32 TryResetBattlerStatChanges(u8 battler)
{
u32 j;
bool32 ret = FALSE;
gDisableStructs[battler].stockpileDef = 0;
gDisableStructs[battler].stockpileSpDef = 0;
for (j = 0; j < NUM_BATTLE_STATS; j++)
{
if (gBattleMons[battler].statStages[j] != DEFAULT_STAT_STAGE)
ret = TRUE; // returns TRUE if any stat was reset
gBattleMons[battler].statStages[j] = DEFAULT_STAT_STAGE;
}
return ret;
}
@ -11280,7 +11285,7 @@ static void Cmd_tryswapitems(void) // trick
static void Cmd_trycopyability(void) // role play
{
u16 defAbility = gBattleMons[gBattlerTarget].ability;
if (gBattleMons[gBattlerAttacker].ability == defAbility
|| defAbility == ABILITY_NONE
|| IsRolePlayBannedAbilityAtk(gBattleMons[gBattlerAttacker].ability)
@ -11428,7 +11433,7 @@ static void Cmd_tryswapabilities(void) // skill swap
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
return;
}
if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
@ -12448,7 +12453,7 @@ static const u16 sTelekinesisBanList[] =
bool32 IsTelekinesisBannedSpecies(u16 species)
{
u32 i;
for (i = 0; i < ARRAY_COUNT(sTelekinesisBanList); i++)
{
if (species == sTelekinesisBanList[i])