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

EV Caps and EV Items #5269

Merged
merged 5 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
16 changes: 16 additions & 0 deletions include/config/ev_caps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef GUARD_CONFIG_EV_CAP_H
#define GUARD_CONFIG_EV_CAP_H

// Constants for EV Cap Types
#define EV_CAP_NONE 0 // Regular behavior, no EV caps are applied
#define EV_CAP_FLAG_LIST 1 // EV cap is chosen according to the first unset flag in `sEVCapFlagMap`
#define EV_CAP_VARIABLE 2 // EV cap is chosen according to the contents of the event variable specified by B_EV_CAP_VARIABLE
#define EV_CAP_NO_GAIN 3 // No EVs can be gained

// Configs for EV Cap
#define B_EV_CAP_TYPE EV_CAP_NONE // [EV_CAP_NONE, EV_CAP_FLAG_LIST, EV_CAP_VARIABLE, EV_CAP_NO_GAIN] choose the type of EV cap to apply#define B_EV_CAP_VARIABLE 12 // event variable used to derive EV cap if B_EV_CAP_TYPE is set to EV_CAP_VARIABLE
#define B_EV_CAP_VARIABLE 8 // event variable used to derive EV cap if B_EV_CAP_TYPE is set to EV_CAP_VARIABLE

#define B_EV_ITEMS_CAP FALSE // If set to true, EV-boosting items can't be used to go over the EV cap

#endif /*GUARD_CONFIG_EV_CAP_H*/
1 change: 1 addition & 0 deletions include/constants/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "config/level_caps.h"
#include "config/pokemon.h"
#include "config/overworld.h"
#include "config/ev_caps.h"

// Invalid Versions show as "----------" in Gen 4 and Gen 5's summary screen.
// In Gens 6 and 7, invalid versions instead show "a distant land" in the summary screen.
Expand Down
10 changes: 10 additions & 0 deletions include/ev_caps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef GUARD_EV_CAP_H
#define GUARD_EV_CAP_H

#if B_EV_CAP_TYPE != EV_CAP_NONE && B_EV_CAP_TYPE != EV_CAP_FLAG_LIST && B_EV_CAP_TYPE != EV_CAP_VARIABLE && B_EV_CAP_TYPE != EV_CAP_NO_GAIN
#error "Invalid choice for B_EV_CAP_TYPE, must be one of [EV_CAP_NONE, EV_CAP_FLAG_LIST, EV_CAP_VARIABLE, EV_CAP_NO_GAIN]"
#endif

u32 GetCurrentEVCap(void);

#endif /* GUARD_EV_CAP_H */
45 changes: 45 additions & 0 deletions src/ev_caps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "global.h"
#include "battle.h"
#include "event_data.h"
#include "ev_caps.h"
#include "pokemon.h"

u32 GetCurrentEVCap(void)
{

static const u16 sEvCapFlagMap[][2] = {
// Define EV caps for each milestone
{FLAG_BADGE01_GET, 16},
{FLAG_BADGE02_GET, 48},
{FLAG_BADGE03_GET, 80},
{FLAG_BADGE04_GET, 112},
{FLAG_BADGE05_GET, 144},
{FLAG_BADGE06_GET, 176},
{FLAG_BADGE07_GET, 208},
{FLAG_BADGE08_GET, 240},
{FLAG_IS_CHAMPION, MAX_TOTAL_EVS},
};

u32 i;

if (B_EV_CAP_TYPE == EV_CAP_FLAG_LIST)
{
for (i = 0; i < ARRAY_COUNT(sEvCapFlagMap); i++)
{
if (!FlagGet(sEvCapFlagMap[i][0]))
{
return sEvCapFlagMap[i][1];
}
}
}
Flash1Lucky marked this conversation as resolved.
Show resolved Hide resolved
else if (B_EV_CAP_TYPE == EV_CAP_VARIABLE)
{
return VarGet(B_EV_CAP_VARIABLE);
}
else if (B_EV_CAP_TYPE == EV_CAP_NO_GAIN)
{
return 0;
}

return MAX_TOTAL_EVS;
}
31 changes: 18 additions & 13 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "constants/union_room.h"
#include "constants/weather.h"
#include "wild_encounter.h"
#include "ev_caps.h"

#define FRIENDSHIP_EVO_THRESHOLD ((P_FRIENDSHIP_EVO_THRESHOLD >= GEN_9) ? 160 : 220)

Expand Down Expand Up @@ -3752,6 +3753,9 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
s8 evChange;
u16 evCount;

// Determine the EV cap to use
u32 maxAllowedEVs = !B_EV_ITEMS_CAP ? MAX_TOTAL_EVS : GetCurrentEVCap();

// Get item hold effect
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
if (heldItem == ITEM_ENIGMA_BERRY_E_READER)
Expand Down Expand Up @@ -3880,25 +3884,25 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (evChange > 0) // Increasing EV (HP or Atk)
{
// Has EV increase limit already been reached?
if (evCount >= MAX_TOTAL_EVS)
if (evCount >= maxAllowedEVs)
return TRUE;

if (itemEffect[10] & ITEM10_IS_VITAMIN)
evCap = EV_ITEM_RAISE_LIMIT;
else
evCap = MAX_PER_STAT_EVS;

if (dataSigned >= evCap)
if (B_EV_ITEMS_CAP && dataSigned >= evCap)
break;

// Limit the increase
if (dataSigned + evChange > evCap)
if (B_EV_ITEMS_CAP && dataSigned + evChange > evCap)
temp2 = evCap - (dataSigned + evChange) + evChange;
else
temp2 = evChange;

if (evCount + temp2 > MAX_TOTAL_EVS)
temp2 += MAX_TOTAL_EVS - (evCount + temp2);
if (evCount + temp2 > maxAllowedEVs)
temp2 += maxAllowedEVs - (evCount + temp2);

dataSigned += temp2;
}
Expand Down Expand Up @@ -4065,25 +4069,25 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (evChange > 0) // Increasing EV
{
// Has EV increase limit already been reached?
if (evCount >= MAX_TOTAL_EVS)
if (evCount >= maxAllowedEVs)
return TRUE;

if (itemEffect[10] & ITEM10_IS_VITAMIN)
evCap = EV_ITEM_RAISE_LIMIT;
else
evCap = MAX_PER_STAT_EVS;

if (dataSigned >= evCap)
if (B_EV_ITEMS_CAP && dataSigned >= evCap)
break;

// Limit the increase
if (dataSigned + evChange > evCap)
if (B_EV_ITEMS_CAP && dataSigned + evChange > evCap)
temp2 = evCap - (dataSigned + evChange) + evChange;
else
temp2 = evChange;

if (evCount + temp2 > MAX_TOTAL_EVS)
temp2 += MAX_TOTAL_EVS - (evCount + temp2);
if (evCount + temp2 > maxAllowedEVs)
temp2 += maxAllowedEVs - (evCount + temp2);

dataSigned += temp2;
}
Expand Down Expand Up @@ -5195,6 +5199,7 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
int i, multiplier;
u8 stat;
u8 bonus;
u32 currentEVCap = GetCurrentEVCap(); // Get the current EV cap
Copy link
Collaborator

Choose a reason for hiding this comment

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

the comment is redundant since it restates the function name.


heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
if (heldItem == ITEM_ENIGMA_BERRY_E_READER)
Expand Down Expand Up @@ -5224,7 +5229,7 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)

for (i = 0; i < NUM_STATS; i++)
{
if (totalEVs >= MAX_TOTAL_EVS)
if (totalEVs >= currentEVCap) // Use currentEVCap instead of MAX_TOTAL_EVS
Copy link
Collaborator

Choose a reason for hiding this comment

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

comment seems redundant here as well.

break;

if (CheckPartyHasHadPokerus(mon, 0))
Expand Down Expand Up @@ -5275,8 +5280,8 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
evIncrease *= 2;

if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS)
evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease);
if (totalEVs + (s16)evIncrease > currentEVCap) // Use currentEVCap instead of MAX_TOTAL_EVS
Copy link
Collaborator

Choose a reason for hiding this comment

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

also comment not needed here

Copy link
Author

Choose a reason for hiding this comment

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

Removed all the unnecessary comments.

evIncrease = ((s16)evIncrease + currentEVCap) - (totalEVs + evIncrease);

if (evs[i] + (s16)evIncrease > MAX_PER_STAT_EVS)
{
Expand Down
Loading