• Hi, Guest!
    Some images might be missing as we move away from using embedded images, sorry for the mess!
    From now on, you'll be required to use a third party to host images. You can learn how to add images here, and if your thread is missing images you can request them here.
    Do not use Discord to host any images you post, these links expire quickly!
Simple and Customizable Level Caps

Resource Simple and Customizable Level Caps 1.0

Golisopod User

Elite Trainer
Member
Joined
May 11, 2020
Posts
319
Golisopod User submitted a new resource:

Simple and Customizable Level Caps - Easy to set up and use Level Caps in Pokemon Essentials

Simple & Customizable Level Caps


View attachment 571View attachment 572
Overview:
With the new Essentials v18 came many script changes that made older battle-related scripts incompatible. One of these was the method to add level caps. My original aim was just to make a plug-and-play version of that. However there was a myriad of other changes I ended up making to...

Read more about this resource...
 

DarrylBD99

A YouTuber that really REALLY loves making games
Member
Joined
May 20, 2020
Posts
60
I tested it and it is able to hard cap Rare Candy, but it doesn't really work when it comes to battling and exp candy...

Edit: Found my problem, I just changed all pkmn.level>levelCap to pkmn.level>=levelCap (except for rare candy). Not sure if this is a mistake...
 
Last edited:

Golisopod User

Elite Trainer
Member
Joined
May 11, 2020
Posts
319
Found my problem, I just changed all pkmn.level>levelCap to pkmn.level>=levelCap (except for rare candy). Not sure if this is a mistake...
It isn't. Because if I made them ">=" then the Pokemon would stop gaining EXP before reaching the level cap. Eg: If my Level Cap is 40 then I'd want to prevent my Pokemon from going to Lv 41, not Lv 40.
 

DarrylBD99

A YouTuber that really REALLY loves making games
Member
Joined
May 20, 2020
Posts
60
It isn't. Because if I made them ">=" then the Pokemon would stop gaining EXP before reaching the level cap. Eg: If my Level Cap is 40 then I'd want to prevent my Pokemon from going to Lv 41, not Lv 40.
but the problem is that for me, it isn't preventing it to go to level 41
 

Golisopod User

Elite Trainer
Member
Joined
May 11, 2020
Posts
319
but the problem is that for me, it isn't preventing it to go to level 41
Did you set HARD_CAP to true in the Customizable Options?
 

SebastiaanZ

Trainer
Member
Joined
Jun 5, 2019
Posts
58
Whatever I am trying, my Pokemon still gain experience after hitting the level cap, especially if the Pokemon gains multiple levels at once. Is there any way to put a hard stop on that?
 

AiurJordan

twitch.tv/aiurjordan
Member
Joined
Aug 10, 2019
Posts
83
Hey Golisopod, I'm working hard to try to get this running in v19.1 Hotfix, but I can't seem to get this EXPCANDY thing to work, I get the error NIL CANT BE COERCED INTO INTEGER at the marked line, however I can't understand why it's nil. I have everything else in the script working but if you were feeling so kind as to help me out just a bit on this I would deeply appreciate it. Thank you for the great script!
Ruby:
ItemHandlers::UseOnPokemon.add(:EXPCANDYXS,proc { |item,pkmn,scene|
   if pkmn.level>=GameData::GrowthRate.max_level || (pokemon.isShadow? rescue false)
     scene.pbDisplay(_INTL("It won't have any effect."))
     return false
   else
     current_lv = pkmn.level
     current_exp = pkmn.exp
     experience=100   if isConst?(item,GameData::Item.get(item).name,:EXPCANDYXS)
     experience=800   if isConst?(item,GameData::Item.get(item).name,:EXPCANDYS)
     experience=3000  if isConst?(item,GameData::Item.get(item).name,:EXPCANDYM)
     experience=10000 if isConst?(item,GameData::Item.get(item).name,:EXPCANDYL)
     experience=30000 if isConst?(item,GameData::Item.get(item).name,:EXPCANDYXL)
     new_exp=pkmn.growth_rate.add_exp(current_exp,experience) ##NIL CANT BE COERCED INTO INTEGER
     newlevel = pkmn.growth_rate.level_from_exp(new_exp)
     leveldif = newlevel - current_lv
     levelCap=GameData::GrowthRate.max_level

     if GYM_BASED
       levelCap=LEVEL_CAPS[$Trainer.numbadges]
     else
       levelCap=LEVEL_CAPS[$game_variables[VARIABLE_USED]]
     end
     levelCap = GameData::GrowthRate.max_level if !levelCap.is_a?(Numeric)
     if leveldif>1 && newlevel > levelCap && !$DEBUG
       scene.pbDisplay(_INTL("{1} refuses to eat the Candy.",pkmn.name))
       next false
     end
     if pkmn.growth_rate.minimum_exp_for_level(newlevel) < (pkmn.exp + experience)
       scene.pbDisplay(_INTL("Your Pokémon gained {1} Exp. Points!",experience))
     else
       scene.pbDisplay(_INTL("Your Pokémon gained {1} Exp. Points!",experience))
     end
     if newlevel==curlevel
       pkmn.exp=newexp
       pkmn.calc_stats
       scene.pbRefresh
     else
       leveldif.times do
         pbChangeLevel(pkmn,pkmn.level+1,scene)
         scene.pbHardRefresh
       end
       next true
     end
   end
})

And here is the entire script just incase you wanted to see it.

Ruby:
#==============================================================================#
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#
#==============================================================================#
#                                                                              #
#                        Simple Customizable Level Caps                        #
#                                     v1.0                                     #
#                               By Golisopod User                              #
#                                                                              #
#==============================================================================#
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#
#==============================================================================#
#                                                                              #
# Implements very simple level caps feature in Pokemon Essentials. The script  #
# not only blocks gaining experience in battle. It also prevents any level     #
# up attempts outside battles. It also blocks any attempts to use Rare Candies #
# and EXP Candies. There are 2 main Level Cap methods in this script.          #
#                                                                              #
# Hard Cap: Similar to Pokemon Reborn, the Pokemon will not gain any exp       #
#           once it has reached the Level Cap. It will block usage of all      #
#           items as well.                                                     #
#                                                                              #
# Soft Cap: Similar to Pokemon Clover, the Pokemon will only gain a fraction   #
#           exp it would gain once it has reached the Level Cap. It will block #
#           usage of all items as well.                                        #
#                                                                              #
# This Script is meant for the default Essentials v18. I have no plan for      #
# supporting older versions.                                                   #
#                                                                              #
#==============================================================================#
#                              INSTRUCTIONS                                    #
#------------------------------------------------------------------------------#
# 1. Place this in a New Script Section above Main                             #
# 2. Edit the Customizable Options                                             #
# 3. Start a new save (Not nescessary, but just to be on the safe side)        #
#                                                                              #
# Note that the level caps aren't applied when in Debug Mode.                  #
#------------------------------------------------------------------------------#
#                          CUSTOMIZABLE OPTIONS                                #
#==============================================================================#
GYM_BASED = true # Set this to true if you want the Lv Caps to use the number of
                 # badges as the factor to decide the level cap

HARD_CAP = false # Set this to true if you want the Lv Caps to use the number of
                 # badges as the factor to decide the level cap

VARIABLE_USED = 0 # Set this to a game variable number if you want the Lv Caps
                  # to use a value other than game variables. If this is set
                  # then GYM_BASED must be set to false.

LEVEL_CAPS = [10,20,30,40,50,60,70,80,100] # Array to store the level caps.
                                           # The cap is determined by Array
                                           # Index. So if tour variable is value
                                           # 4 or you are at the 4th Gym, then the
                                           # cap will be the the (4+1)th value
                                           # in the array. (In this case 50)
#==============================================================================#
#//////////////////////////////////////////////////////////////////////////////#
#==============================================================================#

class PokeBattle_Battle
  def pbGainExpOne(idxParty,defeatedBattler,numPartic,expShare,expAll,showMessages=true)
    pkmn = pbParty(0)[idxParty]   # The Pokémon gaining EVs from defeatedBattler
    growth_rate = pkmn.growth_rate
    # Don't bother calculating if gainer is already at max Exp
    if pkmn.exp>=growth_rate.maximum_exp
      pkmn.calc_stats   # To ensure new EVs still have an effect
      return
    end
    isPartic    = defeatedBattler.participants.include?(idxParty)
    hasExpShare = expShare.include?(idxParty)
    level = defeatedBattler.level
    # Main Exp calculation
    exp = 0
    a = level*defeatedBattler.pokemon.base_exp
    if expShare.length>0 && (isPartic || hasExpShare)
      if numPartic==0   # No participants, all Exp goes to Exp Share holders
        exp = a / (Settings::SPLIT_EXP_BETWEEN_GAINERS ? expShare.length : 1)
      elsif Settings::SPLIT_EXP_BETWEEN_GAINERS   # Gain from participating and/or Exp Share
        exp = a/(2*numPartic) if isPartic
        exp += a/(2*expShare.length) if hasExpShare
      else   # Gain from participating and/or Exp Share (Exp not split)
        exp = (isPartic) ? a : a/2
      end
    elsif isPartic   # Participated in battle, no Exp Shares held by anyone
      exp = a / (Settings::SPLIT_EXP_BETWEEN_GAINERS ? numPartic : 1)
    elsif expAll   # Didn't participate in battle, gaining Exp due to Exp All
      # NOTE: Exp All works like the Exp Share from Gen 6+, not like the Exp All
      #       from Gen 1, i.e. Exp isn't split between all Pokémon gaining it.
      exp = a/2
    end
    return if exp<=0
    # Pokémon gain more Exp from trainer battles
    exp = (exp*1.5).floor if trainerBattle?
    # Scale the gained Exp based on the gainer's level (or not)
    if Settings::SCALED_EXP_FORMULA
      exp /= 5
      levelAdjust = (2*level+10.0)/(pkmn.level+level+10.0)
      levelAdjust = levelAdjust**5
      levelAdjust = Math.sqrt(levelAdjust)
      exp *= levelAdjust
      exp = exp.floor
      exp += 1 if isPartic || hasExpShare
    else
      exp /= 7
    end
    # Foreign Pokémon gain more Exp
    isOutsider = (pkmn.owner.id != pbPlayer.id ||
                 (pkmn.owner.language !=0 && pkmn.owner.language != pbPlayer.language))
    if isOutsider
      if pkmn.owner.language != 0 && pkmn.owner.language != pbPlayer.language
        exp = (exp*1.7).floor
      else
        exp = (exp*1.5).floor
      end
    end
    # Modify Exp gain based on pkmn's held item
    i = BattleHandlers.triggerExpGainModifierItem(pkmn.item,pkmn,exp)
    if i<0
      i = BattleHandlers.triggerExpGainModifierItem(@initialItems[0][idxParty],pkmn,exp)
    end
    #exp = (exp*1.5).floor if $PokemonBag.pbHasItem?(:EXPCHARM)
    exp = i if i>=0
    # Make sure Exp doesn't exceed the maximum
    if GYM_BASED
      levelCap=LEVEL_CAPS[$Trainer.numbadges]
    else
      if $game_variables[VARIABLE_USED].is_a(Numeric)
        levelCap=LEVEL_CAPS[$game_variables[VARIABLE_USED]]
      else
        levelCap = GameData::GrowthRate.max_level
      end
    end
    levelCap = GameData::GrowthRate.max_level if !levelCap.is_a?(Numeric)
    return if pkmn.level>levelCap && !$DEBUG && HARD_CAP
    if pkmn.level>levelCap && !$DEBUG
      if pkmn.level>levelCap+10
        exp = 2
      else
        exp = (exp/100).floor
      end
      exp = 2 if exp < 2
      expFinal=growth_rate.add_exp(pkmn.exp,2)
    else
      expFinal=growth_rate.add_exp(pkmn.exp,exp)
    end
  #  expFinal=PBExperience.pbAddExperience(pkmn.exp,exp,growth_rate)
    expGained = expFinal-pkmn.exp
    return if expGained<=0
    # "Exp gained" message
    if showMessages
      if pkmn.level>levelCap && !$DEBUG
        pbDisplayPaused(_INTL("{1} gained a meager {2} Exp. Points.",pkmn.name,expGained))
      elsif isOutsider
        pbDisplayPaused(_INTL("{1} got a boosted {2} Exp. Points!",pkmn.name,expGained))
      else
        pbDisplayPaused(_INTL("{1} got {2} Exp. Points!",pkmn.name,expGained))
      end
    end
    curLevel = pkmn.level
    newLevel = growth_rate.level_from_exp(expFinal)
    if newLevel<curLevel
      debugInfo = "Levels: #{curLevel}->#{newLevel} | Exp: #{pkmn.exp}->#{expFinal} | gain: #{expGained}"
      raise RuntimeError.new(
         _INTL("{1}'s new level is less than its\r\ncurrent level, which shouldn't happen.\r\n[Debug: {2}]",
         pkmn.name,debugInfo))
    end
    # Give Exp
    if pkmn.shadowPokemon?
      pkmn.exp += expGained
      return
    end
    tempExp1 = pkmn.exp
    battler = pbFindBattler(idxParty)
    loop do   # For each level gained in turn...
      # EXP Bar animation
      levelMinExp = growth_rate.minimum_exp_for_level(curLevel)
      levelMaxExp = growth_rate.minimum_exp_for_level(curLevel+1)
      tempExp2 = (levelMaxExp<expFinal) ? levelMaxExp : expFinal
      pkmn.exp = tempExp2
      @scene.pbEXPBar(battler,levelMinExp,levelMaxExp,tempExp1,tempExp2)
      tempExp1 = tempExp2
      curLevel += 1
      if curLevel>newLevel
        # Gained all the Exp now, end the animation
        pkmn.calc_stats
        battler.pbUpdate(false) if battler
        @scene.pbRefreshOne(battler.index) if battler
        break
      end
      # Levelled up
      pbCommonAnimation("LevelUp",battler) if battler
      oldTotalHP = pkmn.totalhp
      oldAttack  = pkmn.attack
      oldDefense = pkmn.defense
      oldSpAtk   = pkmn.spatk
      oldSpDef   = pkmn.spdef
      oldSpeed   = pkmn.speed
      if battler && battler.pokemon
        battler.pokemon.changeHappiness("levelup")
      end
      pkmn.calc_stats
      battler.pbUpdate(false) if battler
      @scene.pbRefreshOne(battler.index) if battler
      pbDisplayPaused(_INTL("{1} grew to Lv. {2}!",pkmn.name,curLevel))
      @scene.pbLevelUp(pkmn,battler,oldTotalHP,oldAttack,oldDefense,
                                    oldSpAtk,oldSpDef,oldSpeed)
      # Learn all moves learned at this level
      moveList = pkmn.getMoveList
      moveList.each { |m| pbLearnMove(idxParty,m[1]) if m[0]==curLevel }
    end
  end
end

def pbChangeLevel(pkmn,newlevel,scene)
  newlevel = 1 if newlevel<1
  mLevel = GameData::GrowthRate.max_level
  newlevel = mLevel if newlevel>mLevel
  levelCap=mLevel
  if GYM_BASED
    levelCap=LEVEL_CAPS[$Trainer.numbadges]
  else
    levelCap=LEVEL_CAPS[$game_variables[VARIABLE_USED]]
  end
  levelCap = growth_rate.minimum_exp_for_level if !levelCap.is_a?(Numeric)
  if newlevel > levelCap && !$DEBUG
    pbMessage(_INTL("{1}'s level remained unchanged.",pkmn.name))
    return false
  elsif pkmn.level==newlevel
    pbMessage(_INTL("{1}'s level remained unchanged.",pkmn.name))
  elsif pkmn.level>newlevel
    attackdiff  = pkmn.attack
    defensediff = pkmn.defense
    speeddiff   = pkmn.speed
    spatkdiff   = pkmn.spatk
    spdefdiff   = pkmn.spdef
    totalhpdiff = pkmn.totalhp
    pkmn.level = newlevel
    pkmn.calc_stats
    scene.pbRefresh
    pbMessage(_INTL("{1} dropped to Lv. {2}!",pkmn.name,pkmn.level))
    attackdiff  = pkmn.attack-attackdiff
    defensediff = pkmn.defense-defensediff
    speeddiff   = pkmn.speed-speeddiff
    spatkdiff   = pkmn.spatk-spatkdiff
    spdefdiff   = pkmn.spdef-spdefdiff
    totalhpdiff = pkmn.totalhp-totalhpdiff
    pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
       totalhpdiff,attackdiff,defensediff,spatkdiff,spdefdiff,speeddiff))
    pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
       pkmn.totalhp,pkmn.attack,pkmn.defense,pkmn.spatk,pkmn.spdef,pkmn.speed))
  else
    attackdiff  = pkmn.attack
    defensediff = pkmn.defense
    speeddiff   = pkmn.speed
    spatkdiff   = pkmn.spatk
    spdefdiff   = pkmn.spdef
    totalhpdiff = pkmn.totalhp
    pkmn.level = newlevel
    pkmn.changeHappiness("vitamin")
    pkmn.calc_stats
    scene.pbRefresh
    if scene.is_a?(PokemonPartyScreen)
      scene.pbDisplay(_INTL("{1} grew to Lv. {2}!",pkmn.name,pkmn.level))
    else
      pbMessage(_INTL("{1} grew to Lv. {2}!",pkmn.name,pkmn.level))
    end
    attackdiff  = pkmn.attack-attackdiff
    defensediff = pkmn.defense-defensediff
    speeddiff   = pkmn.speed-speeddiff
    spatkdiff   = pkmn.spatk-spatkdiff
    spdefdiff   = pkmn.spdef-spdefdiff
    totalhpdiff = pkmn.totalhp-totalhpdiff
    pbTopRightWindow(_INTL("Max. HP<r>+{1}\r\nAttack<r>+{2}\r\nDefense<r>+{3}\r\nSp. Atk<r>+{4}\r\nSp. Def<r>+{5}\r\nSpeed<r>+{6}",
       totalhpdiff,attackdiff,defensediff,spatkdiff,spdefdiff,speeddiff),scene)
    pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
       pkmn.totalhp,pkmn.attack,pkmn.defense,pkmn.spatk,pkmn.spdef,pkmn.speed),scene)
    # Learn new moves upon level up
    movelist = pkmn.getMoveList
    for i in movelist
      next if i[0]!=pkmn.level
      pbLearnMove(pkmn,i[1],true) { scene.pbUpdate }
    end
    # Check for evolution
    newspecies = pkmn.check_evolution_on_level_up
    if newspecies
      pbFadeOutInWithMusic {
        evo = PokemonEvolutionScene.new
        evo.pbStartScreen(pkmn,newspecies)
        evo.pbEvolution
        evo.pbEndScreen
        scene.pbRefresh if scene.is_a?(PokemonPartyScreen)
      }
    end
  end
end

ItemHandlers::UseOnPokemon.add(:RARECANDY,proc { |item,pkmn,scene|
  levelCap=GameData::GrowthRate.max_level
  if GYM_BASED
    levelCap=LEVEL_CAPS[$Trainer.numbadges]
  else
    levelCap=LEVEL_CAPS[$game_variables[VARIABLE_USED]]
  end
    levelCap = GameData::GrowthRate.max_level if !levelCap.is_a?(Numeric)
  if pkmn.level>=GameData::GrowthRate.max_level || pkmn.shadowPokemon?
    scene.pbDisplay(_INTL("It won't have any effect."))
    next false
  elsif pkmn.level>levelCap && !$DEBUG
    scene.pbDisplay(_INTL("{1} refuses to eat the Rare Candy.",pkmn.name))
    next false
  end
  pbChangeLevel(pkmn,pkmn.level+1,scene)
  scene.pbHardRefresh
  next true
})

ItemHandlers::UseOnPokemon.add(:EXPCANDYXS,proc { |item,pkmn,scene|
   if pkmn.level>=GameData::GrowthRate.max_level || (pokemon.isShadow? rescue false)
     scene.pbDisplay(_INTL("It won't have any effect."))
     return false
   else
     current_lv = pkmn.level
     current_exp = pkmn.exp
     experience=100   if isConst?(item,GameData::Item.get(item).name,:EXPCANDYXS)
     experience=800   if isConst?(item,GameData::Item.get(item).name,:EXPCANDYS)
     experience=3000  if isConst?(item,GameData::Item.get(item).name,:EXPCANDYM)
     experience=10000 if isConst?(item,GameData::Item.get(item).name,:EXPCANDYL)
     experience=30000 if isConst?(item,GameData::Item.get(item).name,:EXPCANDYXL)
     new_exp=pkmn.growth_rate.add_exp(current_exp,experience) ##NIL CANT BE COERCED INTO INTEGER
     newlevel = pkmn.growth_rate.level_from_exp(new_exp)
     leveldif = newlevel - current_lv
     levelCap=GameData::GrowthRate.max_level

     if GYM_BASED
       levelCap=LEVEL_CAPS[$Trainer.numbadges]
     else
       levelCap=LEVEL_CAPS[$game_variables[VARIABLE_USED]]
     end
     levelCap = GameData::GrowthRate.max_level if !levelCap.is_a?(Numeric)
     if leveldif>1 && newlevel > levelCap && !$DEBUG
       scene.pbDisplay(_INTL("{1} refuses to eat the Candy.",pkmn.name))
       next false
     end
     if pkmn.growth_rate.minimum_exp_for_level(newlevel) < (pkmn.exp + experience)
       scene.pbDisplay(_INTL("Your Pokémon gained {1} Exp. Points!",experience))
     else
       scene.pbDisplay(_INTL("Your Pokémon gained {1} Exp. Points!",experience))
     end
     #leftover_exp = pkmn.exp - pkmn.growth_rate.minimum_exp_for_level(new_level)
     #leftover_exp.clamp(0,(pkmn.growth_rate.minimum_exp_for_level(new_level + 1) - 1))
     if newlevel==curlevel
       pkmn.exp=newexp
       pkmn.calc_stats
       scene.pbRefresh
     else
       leveldif.times do
         pbChangeLevel(pkmn,pkmn.level+1,scene)
         scene.pbHardRefresh
       end
       #pkmn.setExp(pkmn.growth_rate.minimum_exp_for_level(new_level) + leftover_exp)
       next true
     end
   end
})

ItemHandlers::UseOnPokemon.copy(:EXPCANDYXS,:EXPCANDYS,:EXPCANDYM,:EXPCANDYL,:EXPCANDYXL)
 

AiurJordan

twitch.tv/aiurjordan
Member
Joined
Aug 10, 2019
Posts
83
New content so double post, pls forgive mods.

I have successfully ported this to v19, but in order for it to work it has to be loaded below Gen 8 Project because it overwrites the def pbAddExp.
It's a little hacky so it may not work for everyone but if anyone was trying to use this script below are my edits + help from Vendily.
Enjoy!

Found more bugs so redacting the code for now.
 
Last edited:

DarrylBD99

A YouTuber that really REALLY loves making games
Member
Joined
May 20, 2020
Posts
60
New content so double post, pls forgive mods.

I have successfully ported this to v19, but in order for it to work it has to be loaded below Gen 8 Project because it overwrites the def pbAddExp.
It's a little hacky so it may not work for everyone but if anyone was trying to use this script below are my edits + help from Vendily.
Enjoy!

Found more bugs so redacting the code for now.
That is cool and all but... where is the script for that tbe?
 

Golisopod User

Elite Trainer
Member
Joined
May 11, 2020
Posts
319
I think it was irresponsible of me to not clarify this before, so I think I should do it now:
I will no longer be actively maintaining or updating this resource. The latest release of the resource was deleted as it was not compatible with the latest version of Essentials. This resource shouldn't be the reason for someone to stick to an older version of Essentials.
phantombass has a a wonderful plugin called Customizable Level Caps which implements this functionality of this plugin, along with many more things.

I apologize for any inconvenience caused by my extended period of inactivity.
 
Back
Top