Merge pull request #1521 from DizzyEggg/largeexp

Allow larger exp gains
This commit is contained in:
ultima-soul 2021-06-06 13:33:33 -07:00 committed by GitHub
commit 2563bc5c83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 35 deletions

View File

@ -489,7 +489,7 @@ struct BattleStruct
u8 switchInAbilitiesCounter; u8 switchInAbilitiesCounter;
u8 faintedActionsState; u8 faintedActionsState;
u8 faintedActionsBattlerId; u8 faintedActionsBattlerId;
u16 expValue; u32 expValue;
u8 field_52; u8 field_52;
u8 sentInPokes; u8 sentInPokes;
bool8 selectionScriptFinished[MAX_BATTLERS_COUNT]; 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_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u16 abilityId, u8* arg4);
void BtlController_EmitCmd23(u8 bufferId); // unused void BtlController_EmitCmd23(u8 bufferId); // unused
void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue); 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_EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2);
void BtlController_EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status); void BtlController_EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status);
void BtlController_EmitStatusXor(u8 bufferId, u8 b); // unused 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_EmitDMA3Transfer(u8 bufferId, void *dst, u16 size, void *data); // unused
void BtlController_EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter); // unused void BtlController_EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter); // unused
void BtlController_EmitCmd32(u8 bufferId, u16 size, void *c); // 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_EmitChosenMonReturnValue(u8 bufferId, u8 b, u8 *c);
void BtlController_EmitOneReturnValue(u8 bufferId, u16 arg1); void BtlController_EmitOneReturnValue(u8 bufferId, u16 arg1);
void BtlController_EmitOneReturnValue_Duplicate(u8 bufferId, u16 b); void BtlController_EmitOneReturnValue_Duplicate(u8 bufferId, u16 b);

View File

@ -1244,15 +1244,21 @@ static void CompleteOnInactiveTextPrinter(void)
} }
#define tExpTask_monId data[0] #define tExpTask_monId data[0]
#define tExpTask_gainedExp data[1]
#define tExpTask_battler data[2] #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] #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) static void Task_GiveExpToMon(u8 taskId)
{ {
u32 monId = (u8)(gTasks[taskId].tExpTask_monId); u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
u8 battlerId = gTasks[taskId].tExpTask_battler; 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. 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) static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
{ {
u8 monIndex = gTasks[taskId].tExpTask_monId; u8 monIndex = gTasks[taskId].tExpTask_monId;
s32 gainedExp = gTasks[taskId].tExpTask_gainedExp; s32 gainedExp = GetTaskExpValue(taskId);
u8 battlerId = gTasks[taskId].tExpTask_battler; u8 battlerId = gTasks[taskId].tExpTask_battler;
struct Pokemon *mon = &gPlayerParty[monIndex]; struct Pokemon *mon = &gPlayerParty[monIndex];
u8 level = GetMonData(mon, MON_DATA_LEVEL); u8 level = GetMonData(mon, MON_DATA_LEVEL);
@ -1322,9 +1328,9 @@ static void Task_GiveExpWithExpBar(u8 taskId)
else else
{ {
u8 monId = gTasks[taskId].tExpTask_monId; u8 monId = gTasks[taskId].tExpTask_monId;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp; s32 gainedExp = GetTaskExpValue(taskId);
u8 battlerId = gTasks[taskId].tExpTask_battler; u8 battlerId = gTasks[taskId].tExpTask_battler;
s16 newExpPoints; s32 newExpPoints;
newExpPoints = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0); newExpPoints = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]);
@ -2833,6 +2839,7 @@ static void PlayerHandleHealthBarUpdate(void)
static void PlayerHandleExpUpdate(void) static void PlayerHandleExpUpdate(void)
{ {
u8 monId = gBattleResources->bufferA[gActiveBattler][1]; u8 monId = gBattleResources->bufferA[gActiveBattler][1];
s32 taskId, expPointsToGive;
if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL) if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL)
{ {
@ -2840,23 +2847,22 @@ static void PlayerHandleExpUpdate(void)
} }
else else
{ {
s16 expPointsToGive;
u8 taskId;
LoadBattleBarGfx(1); LoadBattleBarGfx(1);
GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); // Unused return value. 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); taskId = CreateTask(Task_GiveExpToMon, 10);
gTasks[taskId].tExpTask_monId = monId; 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; gTasks[taskId].tExpTask_battler = gActiveBattler;
gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy; gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy;
} }
} }
#undef tExpTask_monId #undef tExpTask_monId
#undef tExpTask_gainedExp
#undef tExpTask_battler #undef tExpTask_battler
#undef tExpTask_gainedExp_1
#undef tExpTask_gainedExp_2
#undef tExpTask_frames #undef tExpTask_frames
static void PlayerHandleStatusIconUpdate(void) static void PlayerHandleStatusIconUpdate(void)

View File

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

View File

@ -3688,7 +3688,7 @@ static void Cmd_getexp(void)
u8 holdEffect; u8 holdEffect;
s32 sentIn; s32 sentIn;
s32 viaExpShare = 0; s32 viaExpShare = 0;
u16 *exp = &gBattleStruct->expValue; u32 *exp = &gBattleStruct->expValue;
gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1]; sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1];
@ -3715,7 +3715,7 @@ static void Cmd_getexp(void)
break; break;
case 1: // calculate experience points to redistribute case 1: // calculate experience points to redistribute
{ {
u16 calculatedExp; u32 calculatedExp;
s32 viaSentIn; s32 viaSentIn;
for (viaSentIn = 0, i = 0; i < PARTY_SIZE; i++) for (viaSentIn = 0, i = 0; i < PARTY_SIZE; i++)
@ -3822,9 +3822,14 @@ static void Cmd_getexp(void)
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && B_TRAINER_EXP_MULTIPLIER <= GEN_7) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && B_TRAINER_EXP_MULTIPLIER <= GEN_7)
gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; gBattleMoveDamage = (gBattleMoveDamage * 150) / 100;
#if (B_SCALED_EXP >= GEN_5) && (B_SCALED_EXP != GEN_6) #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]; // Note: There is an edge case where if a pokemon receives a large amount of exp, it wouldn't be properly calculated
gBattleMoveDamage++; // 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 #endif
if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId])) if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId]))
@ -3866,7 +3871,7 @@ static void Cmd_getexp(void)
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, gBattleStruct->expGetterMonId); PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, gBattleStruct->expGetterMonId);
// buffer 'gained' or 'gained a boosted' // buffer 'gained' or 'gained a boosted'
PREPARE_STRING_BUFFER(gBattleTextBuff2, i); PREPARE_STRING_BUFFER(gBattleTextBuff2, i);
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage); PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 6, gBattleMoveDamage);
PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBattlerId); PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBattlerId);
MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species); MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species);
@ -3912,7 +3917,7 @@ static void Cmd_getexp(void)
BattleScriptPushCursor(); BattleScriptPushCursor();
gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterMonId]; gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterMonId];
gBattlescriptCurrInstr = BattleScript_LevelUp; 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); AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterMonId], FRIENDSHIP_EVENT_GROW_LEVEL);
// update battle mon structure after level up // update battle mon structure after level up