• 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.
  • The Eevee Expo Game Jam has concluded! 🎉 Head on over to the game jam forum to play through the games.
    Don't forget to come back September 21st to vote for your favorites!
  • Reminder: AI-generated content is not allowed on the forums per the Rules and Regulations. Please contact us if you have any questions!

Modifying EXP gain to a fixed value determined by encounter

WaddleBih

Rookie
Member
Joined
Nov 27, 2024
Posts
4
Hello!
I am currently using Essentials (version 21.1 with hotfixes) to try and recreate an old GBC Pokémon clone.
Issue is: while its systems are very Pokémon-adjacent, a lot of things are not. One of these systems is, that EXP gain is not calculated and instead is a fixed value per-encounter (both wild and "trainers", I'm focusing on the wild encounters for now).
So far, tinkering with the scripts has allowed me to enter the value on the encounter slot, export it to the PBS file and compile that value into the .dat version. Now all I need is for the game to actually get the value from the encounter list and get it all the way over to where the EXP gain is (Battle_ExpAndMoveLearning if I understand the structure correctly). I'm not very proficient with Ruby yet, is there an efficient way to carry the data from one script to another? So far, I've only managed to get it up to the generate_foes function of the Overworld_BattleStarting script.

Short version:

I need to get this data from the encounters PBS/dat file

to the exp value in Battle_ExpAndMoveLearning (set it to 0 as placeholder and so far it works):


Thank you in advance!
 
Figured out a way! I'll post it here if other people want to make a similar EXP gain system.
(Note that this will only cover how to make it work in the battle code, not how to create the new value slots themselves; it's easy enough to figure out)

First of all, in in the Pokemon script, add a new attr_accessor called "exp_to_gain" and set it to 0 in the "initialize" portion of the script, here:
Ruby:
Expand Collapse Copy
  # Creates a new Pokémon object.
  # @param species [Symbol, String, GameData::Species] Pokémon species
  # @param level [Integer] Pokémon level
  # @param owner [Owner, Player, NPCTrainer] Pokémon owner (the player by default)
  # @param withMoves [Boolean] whether the Pokémon should have moves
  # @param recheck_form [Boolean] whether to auto-check the form
  def initialize(species, level, owner = $player, withMoves = true, recheck_form = true)
    species_data = GameData::Species.get(species)
    @species          = species_data.species
    @form             = species_data.base_form
    @forced_form      = nil
    @time_form_set    = nil
    self.level        = level
    @steps_to_hatch   = 0
    heal_status
    @gender           = nil
    @shiny            = nil
    @ability_index    = nil
    @ability          = nil
    @nature           = nil
    @nature_for_stats = nil
    @item             = nil
    @item2            = nil
    @mail             = nil
    @moves            = []
    reset_moves if withMoves
    @first_moves      = []
    @ribbons          = []
    @cool             = 0
    @beauty           = 0
    @cute             = 0
    @smart            = 0
    @tough            = 0
    @sheen            = 0
    @pokerus          = 0
    @name             = nil
    @happiness        = species_data.happiness
    @poke_ball        = :POKEBALL
    @markings         = []
    @iv               = {}
    @ivMaxed          = {}
    @ev               = {}
    @exp_to_gain      = 0
    GameData::Stat.each_main do |s|
      @iv[s.id]       = rand(IV_STAT_LIMIT + 1)
      @ev[s.id]       = 0
    end

Then, in Overworld_BattleStarting, in the self.generate_foes function, make sure to fetch the exp value you set in the Encounters pbs file. If you didn't add anything in-between, it should be arg[2]:
Ruby:
Expand Collapse Copy
  def self.generate_foes(*args)
    ret = []
    species_id = nil
    args.each do |arg|
      case arg
      when Pokemon
        raise _INTL("Species {1} was given but not a level.", species_id) if species_id
        ret.push(arg)
      when Array
        raise _INTL("Species {1} was given but not a level.", species_id) if species_id
        species = GameData::Species.get(arg[0]).id
#        exp = arg[2]
#print(exp)
        money = arg[3]
#print(money)
 pkmn = pbGenerateWildPokemon(species, arg[1], arg[2], arg[3])
        ret.push(pkmn)
#print(pkmn.exp)
#print(pkmn.money)
      else
        if species_id   # Expecting level
          if !arg.is_a?(Integer) || !(1..GameData::GrowthRate.max_level).include?(arg)
            raise _INTL("Expected a level (1..{1}) but {2} is not a number or not a valid level.", GameData::GrowthRate.max_level, arg)
          end
          ret.push(pbGenerateWildPokemon(species_id, arg, arg[2], arg[3]))
          species_id = nil
        else   # Expecting species ID
          if !GameData::Species.exists?(arg)
            raise _INTL("Species {1} does not exist.", arg, arg[2], arg[3])
          end
          species_id = arg
        end
      end
    end
    raise _INTL("Species {1} was given but not a level.", species_id) if species_id
    return ret
  end
end
(ignore the arg[3] and money stuff I'm still figuring that part out, unless you want to get money from wild encounters you won't be needing it anyway.

Then, in Overworld_WildEncounters, in pbGenerateWildPokemon, add an "exp" argument to the function and make sure to set the genwildpoke.exp_to_gain to the function's exp argument value.
Ruby:
Expand Collapse Copy
def pbGenerateWildPokemon(species, level, isRoamer = false, exp, money)
#print(exp)
#print(money)
genwildpoke = Pokemon.new(species, level, exp)
genwildpoke.exp_to_gain = exp
#genwildpoke.getMoney = money
  # Give the wild Pokémon a held item
  items = genwildpoke.wildHoldItems
  first_pkmn = $player.first_pokemon
  chances = [80, 30, 5]
  if first_pkmn
    case first_pkmn.ability_id
    when :COMPOUNDEYES
      chances = [60, 20, 5]
    when :SUPERLUCK
      chances = [60, 20, 5] if Settings::MORE_ABILITIES_AFFECT_WILD_ENCOUNTERS
    end
  end
  itemrnd = rand(100)
  if (items[0] == items[1] && items[1] == items[2]) || itemrnd < chances[0]
    genwildpoke.itemThief = items[0].sample
  elsif itemrnd < (chances[0] + chances[1])
    genwildpoke.itemThief = items[1].sample
  elsif itemrnd < (chances[0] + chances[1] + chances[2])
    genwildpoke.itemThief = items[2].sample
  end

Finally, in Battle_ExpAndMoveLearning, in pbExpGainOne, set a to be "a = defeatedBattler.pokemon.exp_to_gain" instead of "a = level * defeatedBattler.pokemon.base_exp" and REMOVE the exp /= 7 under the SCALED_EXP_FORMULA section (make sure you do not have Scaled EXP active either, or you're not going to get the value you entered).

Et voila! Enjoy your odd, but fully-controlled EXP gain from wild encounters!

NOTE: You'll also need to edit trainer PBS files & compilers so that their pokémon get their fixed EXP value too, or stuff will break.
 
Back
Top