To be clear - this is in the player's options menu?There is also a switch to disable the level cap should you wish to do so.
To be clear - this is in the player's options menu?There is also a switch to disable the level cap should you wish to do so.
Please, help me, I'm having the same issueI have been able to solve my issue in case anyone else ends up experiencing a similar problem to me just message me and I'll be happy to help.
## New Level Cap System
# To change the level cap, simply create an event that runs the script:
# $game_system.level_cap = <new value>
# To change the exp reduction rate, simply create an event that runs the script:
# $game_system.exp_reduction_rate = <new value>
# NOTE: If you have a saved game, and then start a new game, these values will be
# whatever they were set to in the old saved game. So in the game-intro's script you can
# either set them or run "$game_system.initialize" ,
# or, to always do it automatically, add "$game_system.initialize"
# to the ./Data/Scripts/003_GameProcessing/001_StartGame.rb function "def self.start_new"
class Game_System
attr_accessor :level_cap
attr_accessor :exp_reduction_rate
alias initialize_cap initialize
def initialize
@level_cap = 100
@exp_reduction_rate = 5
end
def level_cap
return @level_cap
end
end
class Battle
def pbGainExpOne(idxParty, defeatedBattler, numPartic, expShare, expAll, showMessages = true)
pkmn = pbParty(0)[idxParty] # The Pokémon gaining Exp 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
level_cap = $game_system.level_cap
level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp
exp_reduction_rate = $game_system.exp_reduction_rate
Console.echo_lblue _INTL("\n\n[LEVEL CAP] lvl_cap: %d , reduction_rate: %d" % [level_cap, exp_reduction_rate])
# 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)
reduced_gain = 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced
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
Console.echo _INTL("\n[EXP scale formula] Original EXP earned before lvl_cap check: %d" % [exp])
if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following:
if pkmn.level >= level_cap # If you are over the level cap, receive reduced exp
exp /= exp_reduction_rate
reduced_gain = 1
Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap: Reduce by %d --> New Exp: %d" % [exp_reduction_rate, exp])
else
exp /= (exp_reduction_rate / 2) # If you are within 2 levels of the level cap, receive only partially reduced exp
reduced_gain = 2
Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap -2: Reduce by %d --> New Exp: %d" % [(exp_reduction_rate / 2), exp])
end
end
if pkmn.level < level_cap && exp >= level_cap_gap # If your exp winnings make you reach the level cap, reduce the excess
excess_exp = (exp - level_cap_gap)
exp = level_cap_gap + excess_exp/exp_reduction_rate
reduced_gain = 3
Console.echo _INTL("\n[EXP scale formula] When exp >= level_cap_gap :: Lvl_Cap_Gap: %d , Excess Exp to reduce: %d --> New Exp: %d" % [level_cap_gap, excess_exp, exp])
end
else # If you are not playing on gen 7+ settings...
if a <= level_cap_gap
exp = a
else
exp /= 7
end
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
# Exp. Charm increases Exp gained
exp = exp * 3 / 2 if $bag.has?(:EXPCHARM)
# Modify Exp gain based on pkmn's held item
i = Battle::ItemEffects.triggerExpGainModifier(pkmn.item, pkmn, exp)
if i < 0
i = Battle::ItemEffects.triggerExpGainModifier(@initialItems[0][idxParty], pkmn, exp)
end
exp = i if i >= 0
# Boost Exp gained with high affection
if Settings::AFFECTION_EFFECTS && @internalBattle && pkmn.affection_level >= 4 && !pkmn.mega?
exp = exp * 6 / 5
isOutsider = true # To show the "boosted Exp" message
end
# Make sure Exp doesn't exceed the maximum
expFinal = growth_rate.add_exp(pkmn.exp, exp)
expGained = expFinal - pkmn.exp
Console.echo_lblue _INTL("\n[EXP GAINED] %d" % [expGained])
return if expGained <= 0
# "Exp gained" message
if showMessages
msg_reduction = "got" # Normal xp gain message
if reduced_gain != 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced
msg_reduction = "has little left to learn here and only got" # XP gain message when exp was reduced.
end
if isOutsider
pbDisplayPaused(_INTL("{1} {2} a boosted {3} Exp. Points!", pkmn.name, msg_reduction, expGained))
else
pbDisplayPaused(_INTL("{1} {2} {3} Exp. Points!", pkmn.name, msg_reduction, 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 _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?
if pkmn.heartStage <= 3
pkmn.exp += expGained
$stats.total_exp_gained += expGained
end
return
end
$stats.total_exp_gained += expGained
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)
@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&.pokemon
battler.pokemon.changeHappiness("levelup")
end
pkmn.calc_stats
battler&.pbUpdate(false)
@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
You are a angel, thank you so muchHello,
I saw other comments talking about how this script isn't working for them, so I thought I'd share how I adjusted it to work for my use-case.
Mainly I removed anything related to the UI. I'm not sure what it was supposed to be doing, but since I didn't want anything related to level caps in my UI, I just removed it all.
I also changed how you set the Level Cap and XP Reduction rate to something a lot more friendly to interact with using events. (as described in the comments at the very top of the code block here).
I also liked the idea of having the XP rate slow down as you get closer to the level cap, so I added a chunk about an only slightly-reduced rate when you are within 2 levels of the level cap.
And I wanted the player to know they were getting a reduced xp rate, so I changed the text for when you win a battle and get xp to let you know.
And finally, I often print info in the console that I want to see, so there are some Console.echo commands in here that can be deleted if you want.
./Plugins/Customizable Level Caps/Script.rb:## New Level Cap System # To change the level cap, simply create an event that runs the script: # $game_system.level_cap = <new value> # To change the exp reduction rate, simply create an event that runs the script: # $game_system.exp_reduction_rate = <new value> # NOTE: If you have a saved game, and then start a new game, these values will be # whatever they were set to in the old saved game. So in the game-intro's script you can # either set them or run "$game_system.initialize" , # or, to always do it automatically, add "$game_system.initialize" # to the ./Data/Scripts/003_GameProcessing/001_StartGame.rb function "def self.start_new" class Game_System attr_accessor :level_cap attr_accessor :exp_reduction_rate alias initialize_cap initialize def initialize @level_cap = 100 @exp_reduction_rate = 5 end def level_cap return @level_cap end end class Battle def pbGainExpOne(idxParty, defeatedBattler, numPartic, expShare, expAll, showMessages = true) pkmn = pbParty(0)[idxParty] # The Pokémon gaining Exp 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 level_cap = $game_system.level_cap level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp exp_reduction_rate = $game_system.exp_reduction_rate Console.echo_lblue _INTL("\n\n[LEVEL CAP] lvl_cap: %d , reduction_rate: %d" % [level_cap, exp_reduction_rate]) # 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) reduced_gain = 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced 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 Console.echo _INTL("\n[EXP scale formula] Original EXP earned before lvl_cap check: %d" % [exp]) if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following: if pkmn.level >= level_cap # If you are over the level cap, receive reduced exp exp /= exp_reduction_rate reduced_gain = 1 Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap: Reduce by %d --> New Exp: %d" % [exp_reduction_rate, exp]) else exp /= (exp_reduction_rate / 2) # If you are within 2 levels of the level cap, receive only partially reduced exp reduced_gain = 2 Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap -2: Reduce by %d --> New Exp: %d" % [(exp_reduction_rate / 2), exp]) end end if pkmn.level < level_cap && exp >= level_cap_gap # If your exp winnings make you reach the level cap, reduce the excess excess_exp = (exp - level_cap_gap) exp = level_cap_gap + excess_exp/exp_reduction_rate reduced_gain = 3 Console.echo _INTL("\n[EXP scale formula] When exp >= level_cap_gap :: Lvl_Cap_Gap: %d , Excess Exp to reduce: %d --> New Exp: %d" % [level_cap_gap, excess_exp, exp]) end else # If you are not playing on gen 7+ settings... if a <= level_cap_gap exp = a else exp /= 7 end 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 # Exp. Charm increases Exp gained exp = exp * 3 / 2 if $bag.has?(:EXPCHARM) # Modify Exp gain based on pkmn's held item i = Battle::ItemEffects.triggerExpGainModifier(pkmn.item, pkmn, exp) if i < 0 i = Battle::ItemEffects.triggerExpGainModifier(@initialItems[0][idxParty], pkmn, exp) end exp = i if i >= 0 # Boost Exp gained with high affection if Settings::AFFECTION_EFFECTS && @internalBattle && pkmn.affection_level >= 4 && !pkmn.mega? exp = exp * 6 / 5 isOutsider = true # To show the "boosted Exp" message end # Make sure Exp doesn't exceed the maximum expFinal = growth_rate.add_exp(pkmn.exp, exp) expGained = expFinal - pkmn.exp Console.echo_lblue _INTL("\n[EXP GAINED] %d" % [expGained]) return if expGained <= 0 # "Exp gained" message if showMessages msg_reduction = "got" # Normal xp gain message if reduced_gain != 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced msg_reduction = "has little left to learn here and only got" # XP gain message when exp was reduced. end if isOutsider pbDisplayPaused(_INTL("{1} {2} a boosted {3} Exp. Points!", pkmn.name, msg_reduction, expGained)) else pbDisplayPaused(_INTL("{1} {2} {3} Exp. Points!", pkmn.name, msg_reduction, 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 _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? if pkmn.heartStage <= 3 pkmn.exp += expGained $stats.total_exp_gained += expGained end return end $stats.total_exp_gained += expGained 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) @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&.pokemon battler.pokemon.changeHappiness("levelup") end pkmn.calc_stats battler&.pbUpdate(false) @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
so... I'm getting this errorHello,
I saw other comments talking about how this script isn't working for them, so I thought I'd share how I adjusted it to work for my use-case.
Mainly I removed anything related to the UI. I'm not sure what it was supposed to be doing, but since I didn't want anything related to level caps in my UI, I just removed it all.
I also changed how you set the Level Cap and XP Reduction rate to something a lot more friendly to interact with using events. (as described in the comments at the very top of the code block here).
I also liked the idea of having the XP rate slow down as you get closer to the level cap, so I added a chunk about an only slightly-reduced rate when you are within 2 levels of the level cap.
And I wanted the player to know they were getting a reduced xp rate, so I changed the text for when you win a battle and get xp to let you know.
And finally, I often print info in the console that I want to see, so there are some Console.echo commands in here that can be deleted if you want.
./Plugins/Customizable Level Caps/Script.rb:## New Level Cap System # To change the level cap, simply create an event that runs the script: # $game_system.level_cap = <new value> # To change the exp reduction rate, simply create an event that runs the script: # $game_system.exp_reduction_rate = <new value> # NOTE: If you have a saved game, and then start a new game, these values will be # whatever they were set to in the old saved game. So in the game-intro's script you can # either set them or run "$game_system.initialize" , # or, to always do it automatically, add "$game_system.initialize" # to the ./Data/Scripts/003_GameProcessing/001_StartGame.rb function "def self.start_new" class Game_System attr_accessor :level_cap attr_accessor :exp_reduction_rate alias initialize_cap initialize def initialize @level_cap = 100 @exp_reduction_rate = 5 end def level_cap return @level_cap end end class Battle def pbGainExpOne(idxParty, defeatedBattler, numPartic, expShare, expAll, showMessages = true) pkmn = pbParty(0)[idxParty] # The Pokémon gaining Exp 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 level_cap = $game_system.level_cap level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp exp_reduction_rate = $game_system.exp_reduction_rate Console.echo_lblue _INTL("\n\n[LEVEL CAP] lvl_cap: %d , reduction_rate: %d" % [level_cap, exp_reduction_rate]) # 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) reduced_gain = 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced 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 Console.echo _INTL("\n[EXP scale formula] Original EXP earned before lvl_cap check: %d" % [exp]) if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following: if pkmn.level >= level_cap # If you are over the level cap, receive reduced exp exp /= exp_reduction_rate reduced_gain = 1 Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap: Reduce by %d --> New Exp: %d" % [exp_reduction_rate, exp]) else exp /= (exp_reduction_rate / 2) # If you are within 2 levels of the level cap, receive only partially reduced exp reduced_gain = 2 Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap -2: Reduce by %d --> New Exp: %d" % [(exp_reduction_rate / 2), exp]) end end if pkmn.level < level_cap && exp >= level_cap_gap # If your exp winnings make you reach the level cap, reduce the excess excess_exp = (exp - level_cap_gap) exp = level_cap_gap + excess_exp/exp_reduction_rate reduced_gain = 3 Console.echo _INTL("\n[EXP scale formula] When exp >= level_cap_gap :: Lvl_Cap_Gap: %d , Excess Exp to reduce: %d --> New Exp: %d" % [level_cap_gap, excess_exp, exp]) end else # If you are not playing on gen 7+ settings... if a <= level_cap_gap exp = a else exp /= 7 end 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 # Exp. Charm increases Exp gained exp = exp * 3 / 2 if $bag.has?(:EXPCHARM) # Modify Exp gain based on pkmn's held item i = Battle::ItemEffects.triggerExpGainModifier(pkmn.item, pkmn, exp) if i < 0 i = Battle::ItemEffects.triggerExpGainModifier(@initialItems[0][idxParty], pkmn, exp) end exp = i if i >= 0 # Boost Exp gained with high affection if Settings::AFFECTION_EFFECTS && @internalBattle && pkmn.affection_level >= 4 && !pkmn.mega? exp = exp * 6 / 5 isOutsider = true # To show the "boosted Exp" message end # Make sure Exp doesn't exceed the maximum expFinal = growth_rate.add_exp(pkmn.exp, exp) expGained = expFinal - pkmn.exp Console.echo_lblue _INTL("\n[EXP GAINED] %d" % [expGained]) return if expGained <= 0 # "Exp gained" message if showMessages msg_reduction = "got" # Normal xp gain message if reduced_gain != 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced msg_reduction = "has little left to learn here and only got" # XP gain message when exp was reduced. end if isOutsider pbDisplayPaused(_INTL("{1} {2} a boosted {3} Exp. Points!", pkmn.name, msg_reduction, expGained)) else pbDisplayPaused(_INTL("{1} {2} {3} Exp. Points!", pkmn.name, msg_reduction, 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 _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? if pkmn.heartStage <= 3 pkmn.exp += expGained $stats.total_exp_gained += expGained end return end $stats.total_exp_gained += expGained 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) @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&.pokemon battler.pokemon.changeHappiness("levelup") end pkmn.calc_stats battler&.pbUpdate(false) @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
[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.4]
Exception: TypeError
Message: no implicit conversion from nil to integer
Backtrace:
[Customizable Level Cap] Script.rb:42:in `pbGainExpOne'
149:Battle_ExpAndMoveLearning:39:in `block (2 levels) in pbGainExp'
147:Battle:411:in `block in eachInTeam'
147:Battle:411:in `each'
147:Battle:411:in `each_with_index'
147:Battle:411:in `eachInTeam'
149:Battle_ExpAndMoveLearning:35:in `block in pbGainExp'
149:Battle_ExpAndMoveLearning:13:in `each'
149:Battle_ExpAndMoveLearning:13:in `pbGainExp'
166:Battler_UseMove:512:in `pbUseMove'
[2022-09-25 23:15:57 -0400]
[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.4]
Exception: TypeError
Message: no implicit conversion from nil to integer
Backtrace:
[Customizable Level Cap] Script.rb:42:in `pbGainExpOne'
149:Battle_ExpAndMoveLearning:39:in `block (2 levels) in pbGainExp'
147:Battle:411:in `block in eachInTeam'
147:Battle:411:in `each'
147:Battle:411:in `each_with_index'
147:Battle:411:in `eachInTeam'
149:Battle_ExpAndMoveLearning:35:in `block in pbGainExp'
149:Battle_ExpAndMoveLearning:13:in `each'
149:Battle_ExpAndMoveLearning:13:in `pbGainExp'
212:Battle_CatchAndStoreMixin:174:in `pbThrowPokeBall'
=================
[2022-09-25 23:16:01 -0400]
[Pokémon Essentials version 20.1]
[v20.1 Hotfixes 1.0.4]
Exception: TypeError
Message: no implicit conversion from nil to integer
Backtrace:
[Customizable Level Cap] Script.rb:42:in `pbGainExpOne'
149:Battle_ExpAndMoveLearning:39:in `block (2 levels) in pbGainExp'
147:Battle:411:in `block in eachInTeam'
147:Battle:411:in `each'
147:Battle:411:in `each_with_index'
147:Battle:411:in `eachInTeam'
149:Battle_ExpAndMoveLearning:35:in `block in pbGainExp'
149:Battle_ExpAndMoveLearning:13:in `each'
149:Battle_ExpAndMoveLearning:13:in `pbGainExp'
157:Battle_EndOfRoundPhase:698:in `pbEndOfRoundPhase'
This update simply fixes the issue where the pause menu wouldn't go away when you attempted to close it.
Fixes an unnamed variable
Exception: TypeError
Message: no implicit conversion from nil to integer
Backtrace:
[Customizable Level Cap] Script.rb:42:in `pbGainExpOne'
Line 30: def pbGainExpOne(...)
...
Line 41: level_cap = $game_system.level_cap
Line 42: level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp
Fixes another small glitch
Last bug fix (hopefully)
Fixed pause menu glitches
@RidgeBoy Phantombass has been updating the script a lot today... I'm not sure if your changes that you made to make this work with the Voltseon pause menu will carry over. Would you happen to have a copy of the updated script with your changes flowing through so I can test based on the latest version?@moonlight , @Jos_Louis :
Looks like you're both getting the same error:
The error description:Exception: TypeError Message: no implicit conversion from nil to integer Backtrace: [Customizable Level Cap] Script.rb:42:in `pbGainExpOne'
Which is pointing to line 42 of the plugin script:
Cause of Error:Line 30: def pbGainExpOne(...) ... Line 41: level_cap = $game_system.level_cap Line 42: level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp
I believe what the error is saying is that the variable "level_cap" has no value. So when it searches for the exp needed to level up at that level, it can't search using a variable that has no value.
I set the default value to "100" on line 20 of the script, but that default only activates when "$game_system.initialize" is run. (See the NOTE at the top of the script).
So my guess is that you do not have the default level cap loaded, nor did you manually set a level cap yet in your test?
If my guess is correct, then to fix this, you can do a couple different things:
Please let me know if that fixes your problem!!!
- Follow the NOTE at the top of the script (add "$game_system.initialize" to the game-intro script) to load the default level 100 when you start a new game.
- Or simply add "$game_system.initialize" to an event in your current game, and then interact with that event to load the default level 100 level cap into your current game. (Like, create an event, add "script" to it, and make the script be "$game_system.initialize" without the quotation marks)
- Or, similar to that option, create an event to set the level cap to whatever you want and interact with that event. Like make an event, add "script" to it, and fill that with "$game_system.level_cap = 20" without the quotation marks. (And change "20" to whatever you want the level cap to be).
Final update
## New Level Cap System
# To change the level cap, simply create an event that runs the script:
# $game_system.level_cap = <new value>
# To change the exp reduction rate, simply create an event that runs the script:
# $game_system.exp_reduction_rate = <new value>
# NOTE: If you have a saved game, and then start a new game, these values will be
# whatever they were set to in the old saved game. So in the game-intro's script you can
# either set them or run "$game_system.initialize" ,
# or, to always do it automatically, add "$game_system.initialize"
# to the ./Data/Scripts/003_GameProcessing/001_StartGame.rb function "def self.start_new"
class Game_System
attr_accessor :level_cap
attr_accessor :exp_reduction_rate
alias initialize_cap initialize
def initialize
@level_cap = 100
@exp_reduction_rate = 5
end
def level_cap
return @level_cap
end
end
class Battle
def pbGainExpOne(idxParty, defeatedBattler, numPartic, expShare, expAll, showMessages = true)
pkmn = pbParty(0)[idxParty] # The Pokémon gaining Exp 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
level_cap = $game_system.level_cap
level_cap_gap = growth_rate.exp_values[level_cap] - pkmn.exp
exp_reduction_rate = $game_system.exp_reduction_rate
Console.echo_lblue _INTL("\n\n[LEVEL CAP] lvl_cap: %d , reduction_rate: %d" % [level_cap, exp_reduction_rate])
# 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)
reduced_gain = 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced
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
Console.echo _INTL("\n[EXP scale formula] Original EXP earned before lvl_cap check: %d" % [exp])
if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following:
if pkmn.level >= level_cap # If you are over the level cap, receive reduced exp
exp /= exp_reduction_rate
reduced_gain = 1
Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap: Reduce by %d --> New Exp: %d" % [exp_reduction_rate, exp])
else
exp /= (exp_reduction_rate / 2) # If you are within 2 levels of the level cap, receive only partially reduced exp
reduced_gain = 2
Console.echo _INTL("\n[EXP scale formula] When pkmn.lvl >= lvl_cap -2: Reduce by %d --> New Exp: %d" % [(exp_reduction_rate / 2), exp])
end
end
if pkmn.level < level_cap && exp >= level_cap_gap # If your exp winnings make you reach the level cap, reduce the excess
excess_exp = (exp - level_cap_gap)
exp = level_cap_gap + excess_exp/exp_reduction_rate
reduced_gain = 3
Console.echo _INTL("\n[EXP scale formula] When exp >= level_cap_gap :: Lvl_Cap_Gap: %d , Excess Exp to reduce: %d --> New Exp: %d" % [level_cap_gap, excess_exp, exp])
end
else # If you are not playing on gen 7+ settings...
if a <= level_cap_gap
exp = a
else
exp /= 7
end
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
# Exp. Charm increases Exp gained
exp = exp * 3 / 2 if $bag.has?(:EXPCHARM)
# Modify Exp gain based on pkmn's held item
i = Battle::ItemEffects.triggerExpGainModifier(pkmn.item, pkmn, exp)
if i < 0
i = Battle::ItemEffects.triggerExpGainModifier(@initialItems[0][idxParty], pkmn, exp)
end
exp = i if i >= 0
# Boost Exp gained with high affection
if Settings::AFFECTION_EFFECTS && @internalBattle && pkmn.affection_level >= 4 && !pkmn.mega?
exp = exp * 6 / 5
isOutsider = true # To show the "boosted Exp" message
end
# Make sure Exp doesn't exceed the maximum
expFinal = growth_rate.add_exp(pkmn.exp, exp)
expGained = expFinal - pkmn.exp
Console.echo_lblue _INTL("\n[EXP GAINED] %d" % [expGained])
return if expGained <= 0
# "Exp gained" message
if showMessages
msg_reduction = "got" # Normal xp gain message
if reduced_gain != 0 # 0 = exp gain was not reduced, 1 = exp gain was fully reduced, 2 = exp gain was partially reduced, 3 = pkmn just reached level cap so only overflow exp was reduced
msg_reduction = "has little left to learn here and only got" # XP gain message when exp was reduced.
end
if isOutsider
pbDisplayPaused(_INTL("{1} {2} a boosted {3} Exp. Points!", pkmn.name, msg_reduction, expGained))
else
pbDisplayPaused(_INTL("{1} {2} {3} Exp. Points!", pkmn.name, msg_reduction, 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 _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?
if pkmn.heartStage <= 3
pkmn.exp += expGained
$stats.total_exp_gained += expGained
end
return
end
$stats.total_exp_gained += expGained
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)
@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&.pokemon
battler.pokemon.changeHappiness("levelup")
end
pkmn.calc_stats
battler&.pbUpdate(false)
@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
Yes, that is one of the things I wrote in my message that I added to the script lol.when I set my level cap to 15, it warned me that it was closing in on the level cap when I was level 14, and started reducing my experience. When I then crossed level 15, my experience came down substantially.
if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following:
I did read this part. I was aware there would be a slow down of the experience and I'm actually ok with this feature.Yes, that is one of the things I wrote in my message that I added to the script lol.
Please read my comments before blindly copy/pasting and then being confused about what the code does haha
On line 78 I wrote:
Line 78:if pkmn.level >= level_cap - 2 # If you are at least within 2 levels of the level cap, do the following:
So, if you do not want this feature, just delete " - 2" from that line (just before the ""#")
.
And yeah I did not look to mess with Rare Cadnies and EXP Candies and stuff because that's a whole other chunk of code, so in my game I simply don't give the player enough of that stuff for it to be aproblem. In my game if the level cap is 15 and they rare candy to 16, it doesn't matter much. Apologies if in your game it does!