• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
Resource icon

v21.1 Nature-Based EV Gain, Vitamin Overhaul, and Automatic IV Perfection 1.69

This resource pertains to version 21.1 of Pokémon Essentials.
Pokémon Essentials Version
v20.1 ➖
Still works with the new version of Essentials!

Simply use this code to overwrite your "def pbGainEVsOne(idxParty, defeatedBattler)" code in Battle_ExpAndMoveLearning in Pokemon Essentials!

Code:
Expand Collapse Copy
def pbGainEVsOne(idxParty, defeatedBattler)
  pkmn = pbParty(0)[idxParty]   # The Pokémon gaining EVs from defeatedBattler
  evYield = defeatedBattler.pokemon.evYield
  # Modify EV yield based on pkmn's held item
  if !Battle::ItemEffects.triggerEVGainModifier(pkmn.item, pkmn, evYield)
    Battle::ItemEffects.triggerEVGainModifier(@initialItems[0][idxParty], pkmn, evYield)
  end
  # Double EV gain because of Pokérus
  if pkmn.pokerusStage >= 1   # Infected or cured
    evYield.each_key { |stat| evYield[stat] *= 2 }
  end
  # Check if Pokemon has more than 128 EVs
  totalEVs = pkmn.ev.values.reduce(:+)
  return if totalEVs >= 128
  # Gain EV based on nature
  nature = pkmn.nature.id

###NATURE BASED EV GAIN - MORE LIKE BASED EV GAIN
  case nature
  ##REDUCES SPEED
when :BRAVE
    pkmn.ev[:ATTACK] += 1 if pkmn.ev[:ATTACK] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
when :RELAXED
    pkmn.ev[:DEFENSE] += 1 if pkmn.ev[:DEFENSE] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
when :QUIET
    pkmn.ev[:SPECIAL_ATTACK] += 1 if pkmn.ev[:SPECIAL_ATTACK] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
when   :SASSY
    pkmn.ev[:SPECIAL_DEFENSE] += 1 if pkmn.ev[:SPECIAL_DEFENSE] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
##DOES NOT REDUCE SPEED
    when :LONELY, :ADAMANT, :NAUGHTY
    pkmn.ev[:ATTACK] += 1 if pkmn.ev[:ATTACK] < 64
    pkmn.ev[:SPEED] += 1 if pkmn.ev[:SPEED] < 64
  when :BOLD, :IMPISH, :LAX
    pkmn.ev[:DEFENSE] += 1 if pkmn.ev[:DEFENSE] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
  when :MODEST, :MILD, :RASH
    pkmn.ev[:SPECIAL_ATTACK] += 1 if pkmn.ev[:SPECIAL_ATTACK] < 64
    pkmn.ev[:SPEED] += 1 if pkmn.ev[:SPEED] < 64
  when :CALM, :GENTLE, :CAREFUL
    pkmn.ev[:SPECIAL_DEFENSE] += 1 if pkmn.ev[:SPECIAL_DEFENSE] < 64
        pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64
  when :TIMID, :HASTY, :JOLLY, :NAIVE
    pkmn.ev[:SPEED] += 1 if pkmn.ev[:SPEED] < 64
  else
    pkmn.ev[:HP] += 1 if pkmn.ev[:HP] < 64   # Default to HP
  end
end

def pbEVTotal(pkmn)
  return pkmn.ev.values.inject(:+)
end

Then you find the ItemHandlers code for HP UP, Protein, and other Vitamins and after disabling the Vitamin EV Cap, change your code to this:

Code:
Expand Collapse Copy
ItemHandlers::UseOnPokemonMaximum.add(:HPUP, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:HP, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:HPUP, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:HP, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemonMaximum.add(:PROTEIN, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:ATTACK, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:PROTEIN, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:ATTACK, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemonMaximum.add(:IRON, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:DEFENSE, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:IRON, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:DEFENSE, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemonMaximum.add(:CALCIUM, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:SPECIAL_ATTACK, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:CALCIUM, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:SPECIAL_ATTACK, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemonMaximum.add(:ZINC, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:SPECIAL_DEFENSE, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:ZINC, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:SPECIAL_DEFENSE, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:XSTATS, proc { |item, qty, pkmn, scene|
pbNowResetEVs(pkmn, scene)
      next 1
})

ItemHandlers::UseOnPokemonMaximum.add(:CARBOS, proc { |item, pkmn|
  next pbMaxUsesOfEVRaisingItem(:SPEED, 1, pkmn, Settings::NO_VITAMIN_EV_CAP)
})

ItemHandlers::UseOnPokemon.add(:CARBOS, proc { |item, qty, pkmn, scene|
  next pbUseEVRaisingItem(:SPEED, 1, qty, pkmn, "vitamin", scene, Settings::NO_VITAMIN_EV_CAP)
})

Ah, sweet mathematical 1-to-1 perfection. No more Health Feathers. No more awkwardly dealing with gaining 10 EVs per drink in a game where only every 4th EV matters. No more dealing with a stupid EV drink limit that never should have existed in the first place.

There's a new item of mine in there called Ex-Stats, so be sure to add this to the Items.txt in your PBS folder if you don't want to remove Ex-Stats from my code. Ex-Stats is a convenient Vitamin drink that resets your Pokemon's EVs to zero, perfect for undoing EV distribution mistakes or allowing you to try new EV spreads without needing to reset your game/start over with a new Pokemon! For the Ex-Stats item sprite I use a colour-changed Protein bottle sprite edited to have a big X on the label, but feel free to draw whatever you want for that sprite.

Code:
Expand Collapse Copy
[XSTATS]
Name = Ex-Stats
PortionName = bottle of Ex-Stats
PortionNamePlural = bottles of Ex-Stats
Pocket = 2
Price = 250
SellPrice = 250
FieldUse = OnPokemon
Flags = Fling_30
Description = A nutritious drink for Pokémon. Resets all of a Pokémon's EVs to zero.

And find somewhere to put this "pbNowResetEVs" code.

Code:
Expand Collapse Copy
def pbNowResetEVs(pkmn, scene)
pkmn.ev[:HP] = 0
    pkmn.ev[:ATTACK] = 0
    pkmn.ev[:DEFENSE] = 0
    pkmn.ev[:SPECIAL_ATTACK] = 0
    pkmn.ev[:SPECIAL_DEFENSE] = 0
    pkmn.ev[:SPEED] = 0
    pkmn.calc_stats
    scene.pbDisplay(_INTL("The Pokémon's EVs were reset."))
end

By the way I recommend setting the price of Vitamins to something low like 100 or 50 as players are expected to purchase 64 per stat they want to max and max 2 stats for each Pokemon in the party. Charging 10k for one Zinc would be unreasonable as 64 Zincs and 64 Proteins for one Pokemon makes 128, and 128x10,000 is 1,280,000 per Pokemon and 7,680,000 total for a team of six, maybe more if you plan on training more Pokemon or resetting one with Ex-Stats and feeding that Pokemon even more Vitamins. 128x50 is only 6,400, and 38,400 total for a team of six Pokemon is far more convenient to obtain. Though if you wanted to set your Vitamin prices to 10 or even 1 I certainly wouldn't stop you.

Finally you ensure your Pokemon and the Pokemon of your foes are generated with perfect IVs by default (because unless you're running Hidden Power or Trick Room or want minimal Atk you always want max IVs) using this trick:

Find this code
Code:
Expand Collapse Copy
GameData::Stat.each_main do |s|
@iv[s.id]       = rand(IV_STAT_LIMIT + 1)

And change it to this.

Code:
Expand Collapse Copy
GameData::Stat.each_main do |s|
@iv[s.id]       = 32

Or "@iv[s.id]= 31" if the default 31 is the highest IV possible in your game.

With this code a Pokemon, after battling, will gain one EV based on what stat its nature boosts, and one speed EV. Unless its nature reduces Speed, in which case it will gain HP EVs instead of Speed EVs. If your nature doesn't boost anything, or is not listed here, your EV gain defaults to HP. Pokerus and held items can increase EV gain, too. Best used in a game where the player has control over what Nature a Pokemon has.

If you wish to change which nature boosts what stat or how many EVs you gain from battle or anything else, feel free to change my code to suit your needs.

Why did I spend all this time making this? Well... Let's be real here, EVs and IVs are a silly mechanic executed clumsily and conveyed poorly. Wouldn't surprise me if 98% of Pokemon fans didn't understand this system, or couldn't understand it without googling an explanation. 99.999% of the time you just want your numbers as high as possible. You either max your stats or for no reason at all choose not to or you can't because of bad IVs. Despite being designed to make Pokemon feel more like individuals, the system just bars 99.999% of these "individuals" from ever amounting to anything in a serious competitive environment, or at the very least, just sucking more than they should unless you alter their EVs/IVs/Nature/Ability. Since the days of Dungeons and Dragons, the inspiration for countless Eastern and Western RPGs including Pokemon and the RPG Genre Itself, Point Buy has been a commonly accepted practice. Even Dragon Quest had it. You level up, you distribute your gained stat points.

But Pokemon chooses to hide this system behind a clunky interface that never feels good to work with or work around. Who enjoys grinding wild encounters for hours with RNG manipulation and power items? It'd be worse without the convenience features we've gotten used to. Unknowable Pokemon grant unknowable amounts of EVs after tremendous amounts of grinding? Vitamins that arbitrarily become unuseable after 100 EVs are obtained? Rounding EVs down after dividing them by four for no reason? Don't even get me started on the several rolled dices involved with Pokemon IVs. You know this system is bad because with each game Pokemon takes another baby step towards making a bad system a little less terrible to deal with. I say, overhaul it entirely to make it as clear and easy to interact with as possible, and make getting it over and done with as quick as possible!

My seamless and intuitive system allows the player to purchase 64 of each EV-raising Vitamin he wants and call it a day, undo his mistakes or try new things, or safely ignore EV training completely and just play the game without hurting what your Pokemon is supposed to get good at. It is simply assumed that you want speed and more of whatever your Pokemon's nature boosts on your Pokemon, or whatever your nature boosts and HP if your nature reduces speed, or Speed and HP if your nature boosts Speed, or just HP if your nature doesn't boost anything. If you want to buy 64 Calciums for Pokemon whose nature boosts nothing, or buy 64 Carbos and Zinc and feed them to a Pokemon whose Nature would normally result in gaining Special Attack and HP, feel free to do so.

Note that in my game EVs are not divided by four and rounded down before being added to the Pokemon's stats, they are instead 1 to 1 and capped individually per stat at 64, not 63. As a result a Pokemon's maximum total EVs in my game are 128, not 510.

If your Pokemon game still allows a Pokemon to have up to 510 EVs total and 252 or 256 in any stat, you will need to adjust the maximum EVs the code checks for before adding EVs. Add one EV per battle, or four, that works too.
Credits
Thanks to Pokemon Emerald Rogue for the idea behind nature-based EV gain! The rest is all me!
Giving credit to me for this would be appreciated but it is not necessary. The more games that use this or offer it as an option, the better.
Author
SuperSpyroDragon64
Views
2,214
First release
Last update

Ratings

0.00 star(s) 0 ratings

More resources from SuperSpyroDragon64

Latest updates

  1. bugfixed NowResetEVs

    def pbNowResetEVs(pkmn, scene) pkmn.ev[:HP] = 0 pkmn.ev[:ATTACK] = 0 pkmn.ev[:DEFENSE] =...
Back
Top