Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gen 8 EXP Candies #2142

Merged
merged 19 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ extern const u8 gText_12PoofForgotMove[];
extern const u8 gText_StopLearningMove2[];
extern const u8 gText_MoveNotLearned[];
extern const u8 gText_PkmnElevatedToLvVar2[];
extern const u8 gText_PkmnGainedExp[];
extern const u8 gText_RemoveMailBeforeItem[];
extern const u8 gText_PkmnHoldingItemCantHoldMail[];
extern const u8 gText_MailTransferredFromMailbox[];
Expand Down
36 changes: 26 additions & 10 deletions src/data/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -1354,11 +1354,17 @@ const struct Item gItems[] =

// Candy

#define ONE_HUNDRED 1 << 4
#define ONE_THOUSAND 1 << 5
#define TEN_THOUSAND 1 << 6
#define FULL_LEVEL 1 << 7

[ITEM_RARE_CANDY] =
{
.name = _("Rare Candy"),
.itemId = ITEM_RARE_CANDY,
.price = 10000,
.holdEffectParam = FULL_LEVEL,
.description = sRareCandyDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
Expand All @@ -1371,10 +1377,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy XS"),
.itemId = ITEM_EXP_CANDY_XS,
.price = 20,
.holdEffectParam = 1 | ONE_HUNDRED,
.description = sExpCandyXSDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

Expand All @@ -1383,10 +1390,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy S"),
.itemId = ITEM_EXP_CANDY_S,
.price = 240,
.holdEffectParam = 8 | ONE_HUNDRED,
.description = sExpCandyXSDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

Expand All @@ -1395,10 +1403,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy M"),
.itemId = ITEM_EXP_CANDY_M,
.price = 1000,
.holdEffectParam = 3 | ONE_THOUSAND,
.description = sExpCandyMDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

Expand All @@ -1407,10 +1416,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy L"),
.itemId = ITEM_EXP_CANDY_L,
.price = 3000,
.holdEffectParam = 1 | TEN_THOUSAND,
.description = sExpCandyLDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

Expand All @@ -1419,10 +1429,11 @@ const struct Item gItems[] =
.name = _("Exp.Candy XL"),
.itemId = ITEM_EXP_CANDY_XL,
.price = 10000,
.holdEffectParam = 3 | TEN_THOUSAND,
.description = sExpCandyXLDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_RareCandy,
.flingPower = 30,
},

Expand All @@ -1438,6 +1449,11 @@ const struct Item gItems[] =
.flingPower = 30,
},

#undef ONE_HUNDRED
#undef ONE_THOUSAND
#undef TEN_THOUSAND
#undef FULL_LEVEL

// Medicinal Flutes

[ITEM_BLUE_FLUTE] =
Expand Down
10 changes: 5 additions & 5 deletions src/data/pokemon/item_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,11 +532,11 @@ const u8 *const gItemEffectTable[] =

// Candy
[ITEM_RARE_CANDY - ITEM_POTION] = gItemEffect_RareCandy,
//[ITEM_EXP_CANDY_XS - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_S - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_M - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_L - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
//[ITEM_EXP_CANDY_XL - ITEM_POTION] = gItemEffect_ExpCandy, // Todo
[ITEM_EXP_CANDY_XS - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_S - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_M - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_L - ITEM_POTION] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XL - ITEM_POTION] = gItemEffect_RareCandy,
//[ITEM_DYNAMAX_CANDY - ITEM_POTION] = gItemEffect_DynamaxCandy, // Todo

// Medicinal Flutes
Expand Down
98 changes: 65 additions & 33 deletions src/party_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ EWRAM_DATA u8 gSelectedOrderFromParty[MAX_FRONTIER_PARTY_SIZE] = {0};
static EWRAM_DATA u16 sPartyMenuItemId = 0;
static EWRAM_DATA u16 sUnused = 0;
EWRAM_DATA u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2] = {0}; // bits 0-3 are the current pos of Slot 1, 4-7 are Slot 2, and so on
static EWRAM_DATA u8 sInitialLevel = 0;
static EWRAM_DATA u8 sFinalLevel = 0;

// IWRAM common
void (*gItemUseCB)(u8, TaskFunc);
Expand Down Expand Up @@ -4874,6 +4876,7 @@ static void CB2_ShowSummaryScreenToForgetMove(void)

static void CB2_ReturnToPartyMenuWhileLearningMove(void)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sFinalLevel); // to avoid displaying incorrect level
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, TRUE, PARTY_MSG_NONE, Task_ReturnToPartyMenuWhileLearningMove, gPartyMenu.exitCallback);
}

Expand Down Expand Up @@ -4979,8 +4982,9 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
s16 *arrayPtr = ptr->data;
u16 *itemPtr = &gSpecialVar_ItemId;
bool8 cannotUseEffect;
sInitialLevel = GetMonData(mon, MON_DATA_LEVEL);

if (GetMonData(mon, MON_DATA_LEVEL) != MAX_LEVEL)
if (sInitialLevel != MAX_LEVEL)
{
BufferMonStatsToTaskData(mon, arrayPtr);
cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, *itemPtr, 0);
Expand All @@ -5000,16 +5004,29 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
}
else
{
sFinalLevel = GetMonData(mon, MON_DATA_LEVEL, NULL);
gPartyMenuUseExitCallback = TRUE;
PlayFanfareByFanfareNum(FANFARE_LEVEL_UP);
UpdateMonDisplayInfoAfterRareCandy(gPartyMenu.slotId, mon);
RemoveBagItem(gSpecialVar_ItemId, 1);
GetMonNickname(mon, gStringVar1);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(mon, MON_DATA_LEVEL), STR_CONV_MODE_LEFT_ALIGN, 3);
StringExpandPlaceholders(gStringVar4, gText_PkmnElevatedToLvVar2);
DisplayPartyMenuMessage(gStringVar4, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = Task_DisplayLevelUpStatsPg1;
if (sFinalLevel > sInitialLevel)
{
PlayFanfareByFanfareNum(FANFARE_LEVEL_UP);
ConvertIntToDecimalStringN(gStringVar2, GetMonData(mon, MON_DATA_LEVEL), STR_CONV_MODE_LEFT_ALIGN, 3);
AgustinGDLV marked this conversation as resolved.
Show resolved Hide resolved
StringExpandPlaceholders(gStringVar4, gText_PkmnElevatedToLvVar2);
DisplayPartyMenuMessage(gStringVar4, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = Task_DisplayLevelUpStatsPg1;
}
else
{
PlaySE(SE_USE_ITEM);
gPartyMenuUseExitCallback = FALSE;
StringExpandPlaceholders(gStringVar4, gText_PkmnGainedExp);
DisplayPartyMenuMessage(gStringVar4, FALSE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = task;
}
}
}

Expand Down Expand Up @@ -5042,6 +5059,7 @@ static void Task_DisplayLevelUpStatsPg2(u8 taskId)
{
PlaySE(SE_SELECT);
DisplayLevelUpStatsPg2(taskId);
sInitialLevel += 1; // so the Pokemon doesn't learn a move meant for its previous level
gTasks[taskId].func = Task_TryLearnNewMoves;
}
}
Expand Down Expand Up @@ -5072,44 +5090,58 @@ static void Task_TryLearnNewMoves(u8 taskId)
if (WaitFanfare(0) && ((JOY_NEW(A_BUTTON)) || (JOY_NEW(B_BUTTON))))
{
RemoveLevelUpStatsWindow();
learnMove = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], TRUE);
gPartyMenu.learnMoveState = 1;
switch (learnMove)
for (; sInitialLevel <= sFinalLevel; sInitialLevel++)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sInitialLevel);
learnMove = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], TRUE);
gPartyMenu.learnMoveState = 1;
switch (learnMove)
{
case 0: // No moves to learn
if (sInitialLevel >= sFinalLevel)
PartyMenuTryEvolution(taskId);
break;
case MON_HAS_MAX_MOVES:
DisplayMonNeedsToReplaceMove(taskId);
break;
case MON_ALREADY_KNOWS_MOVE:
gTasks[taskId].func = Task_TryLearningNextMove;
break;
default:
DisplayMonLearnedMove(taskId, learnMove);
break;
}
if (learnMove)
break;
}
}
}

static void Task_TryLearningNextMove(u8 taskId)
{
u16 result;
for (; sInitialLevel <= sFinalLevel; sInitialLevel++)
{
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_LEVEL, &sInitialLevel);
result = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], FALSE);
switch (result)
{
case 0: // No moves to learn
PartyMenuTryEvolution(taskId);
break;
case MON_HAS_MAX_MOVES:
DisplayMonNeedsToReplaceMove(taskId);
break;
case MON_ALREADY_KNOWS_MOVE:
gTasks[taskId].func = Task_TryLearningNextMove;
break;
return;
default:
DisplayMonLearnedMove(taskId, learnMove);
DisplayMonLearnedMove(taskId, result);
break;
}
if (result)
break;
}
}

static void Task_TryLearningNextMove(u8 taskId)
{
u16 result = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], FALSE);

switch (result)
{
case 0: // No moves to learn
if (sInitialLevel >= sFinalLevel)
PartyMenuTryEvolution(taskId);
break;
case MON_HAS_MAX_MOVES:
DisplayMonNeedsToReplaceMove(taskId);
break;
case MON_ALREADY_KNOWS_MOVE:
return;
default:
DisplayMonLearnedMove(taskId, result);
break;
}
}

static void PartyMenuTryEvolution(u8 taskId)
Expand Down
37 changes: 34 additions & 3 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -4708,6 +4708,11 @@ bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex,
} \
}

#define ONE_HUNDRED 1 << 4
#define ONE_THOUSAND 1 << 5
#define TEN_THOUSAND 1 << 6
#define FULL_LEVEL 1 << 7

// Returns TRUE if the item has no effect on the Pokémon, FALSE otherwise
bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, bool8 usedByAI)
{
Expand Down Expand Up @@ -4877,9 +4882,30 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if ((itemEffect[i] & ITEM3_LEVEL_UP)
&& GetMonData(mon, MON_DATA_LEVEL, NULL) != MAX_LEVEL)
{
dataUnsigned = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1];
SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
CalculateMonStats(mon);
if (ItemId_GetHoldEffectParam(item) & FULL_LEVEL)
{
dataUnsigned = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1];
SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
CalculateMonStats(mon);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you move this so it only sets the EXP with Rare Candies and not Exp. candies?

}
AgustinGDLV marked this conversation as resolved.
Show resolved Hide resolved
else
{
u32 species = GetMonData(mon, MON_DATA_SPECIES, NULL);

AgustinGDLV marked this conversation as resolved.
Show resolved Hide resolved
temp1 = ItemId_GetHoldEffectParam(item) & 0x0F;
AgustinGDLV marked this conversation as resolved.
Show resolved Hide resolved
if (ItemId_GetHoldEffectParam(item) & ONE_HUNDRED)
temp1 *= 100;
if (ItemId_GetHoldEffectParam(item) & ONE_THOUSAND)
temp1 *= 1000;
if (ItemId_GetHoldEffectParam(item) & TEN_THOUSAND)
temp1 *= 10000;
dataUnsigned = temp1 + GetMonData(mon, MON_DATA_EXP, NULL);
if (dataUnsigned > gExperienceTables[gBaseStats[species].growthRate][MAX_LEVEL])
dataUnsigned = gExperienceTables[gBaseStats[species].growthRate][MAX_LEVEL];
SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
if (dataUnsigned >= gExperienceTables[gBaseStats[species].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1])
CalculateMonStats(mon);
}
retVal = FALSE;
}

Expand Down Expand Up @@ -5277,6 +5303,11 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
return retVal;
}

#undef ONE_HUNDRED
#undef ONE_THOUSAND
#undef TEN_THOUSAND
#undef FULL_LEVEL

bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId)
{
u32 status = GetMonData(mon, MON_DATA_STATUS, 0);
Expand Down
1 change: 1 addition & 0 deletions src/strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ const u8 gText_PkmnRegainhedHealth[] = _("{STR_VAR_1} regained health.{PAUSE_UNT
const u8 gText_PkmnBecameHealthy[] = _("{STR_VAR_1} became healthy.{PAUSE_UNTIL_PRESS}");
const u8 gText_MovesPPIncreased[] = _("{STR_VAR_1}'s PP increased.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnElevatedToLvVar2[] = _("{STR_VAR_1} was elevated to\nLv. {STR_VAR_2}.");
const u8 gText_PkmnGainedExp[] = _("{STR_VAR_1} gained Exp. Points!{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnBaseVar2StatIncreased[] = _("{STR_VAR_1}'s base {STR_VAR_2}\nstat was raised.{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnFriendlyBaseVar2Fell[] = _("{STR_VAR_1} turned friendly.\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}");
const u8 gText_PkmnAdoresBaseVar2Fell[] = _("{STR_VAR_1} adores you!\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}");
Expand Down