- 11
- Posts
- 6
- Years
- Spain
- Seen Mar 8, 2025
Hi! I'm learning programming and I joined this community because I wanted to share some scripts I did (and I think they are pretty well).
I'm gonna give you some instructions to set up the 6th generation powers that you have. They have several functions: boost your team in battles, increase the gained money, speed up your egg hatching and pokemon growth... In the original games, using this consumes some "energy", which is restored when you close your DS and start walking.
Obviously, it's difficult to walk if you are playing your fan game in your desktop XD, so I created this code adapted to the Essentials scripts. This is how the O Powers works with this script:
Here is the script you need. Put it above main to make it work.
This is the basis to set up O Power. In this thread you have a ZIP with pictures that this code need. You can modify them, but make sure you also modify the coordinates in the Scene_OPowers class.
Now you need to make some changes in your scripts. I recommend you to put comment to point out that you have modified the script, if there was any error.
Attack and defense
I have modified this O Power: Attack makes the leading Pok?mon raise its attack and special attack when it is called out. Defense does it for defense and special defense. To set up this, find in PokeBattle_Battle, in def pbStartBattleCore (line 2515) pbOnActiveAll and put this below it:
Catch
Again, find in PokeBattle_Battle, def pbThrowPokeball and put this above shakes=0 (line 124).
Reward
In the same class, find in def pbEndOfBattle (line 3939) and put this below tmoney*=2 if @doublemoney.
Critical
Now, in PokeBattle_Move, in def pbIsCritical? find c+=1 if attacker.hasWorkingItem(...) (line 582) and put this below it:
Happiness
Go to PokeBattle_Pokemon to def changeHappiness and before @happiness+=gain (line 837) put this:
This will make the gaining happiness multiplies, even giving the Pok?mon an object.
Discount
Go to PScreen_Mart, def pbPokemonMart (line 792). Replace everything that is before stock.compact! and put this (make sure you also change your own methods!):
Encounter and Repel
Go to PField_Encounters, def pbGenerateEncounter, line 321. Put above return nil if rand ...:
Incubation
I have change this proc because it was inadaptable to these scripts. The effect is exactly the same, but more flexible to changes. In PScreen_EggHatching, line 205, comment by putting a =begin ... =end block (like commenting with '#') starting in the method Events.onStepTaken+=proc {|sender,e and add out of the block this:
Warning! Using this method may convert eggsteps (Integer) into Float, so be aware if you are checking an exact number of eggsteps anywhere.
Experience gain
Go back to PokeBattle_Battle section in def pbGainExpOne. Below isConst?(thispoke.itemInitial,PBItems,:LUCKYEGG) (line 1930) put this code:
I also added a Power that makes wild pokemon have 31 IVs according to the given level.
Now you have to put the button in the Pok?Gear.
Add this line in the section PScreen_Pokegear (def pbStartScreen, line 120) below [I@cmdJukebox=-1[/I]
Then a few lines below, above commands[cmdJukebox=commands.length]=_INTL("Jukebox") put this line:
Now, in the loop, (line 149) add this condition:
And Now the code is set! All you have to do is activate O-Powers in the adventure by using this code:n
Being X the internal name of the O-Power (defined in module OPowers) and level the number to sum to the current level (if you don't specify, by default is 1). This will allow the player to find the menu in the PokeGear and update that O Power.
The attribute $PokemonGlobal.oplevels is an Array of the current level of each O Power id. If it is empty, the PokeGear won't show the O Power button. $PokemonGlobal.opower_data Array stores the current working O Power wich also relates each O Power id with the launched O Power ([level,launch time,duration] or nil if none). $PokemonGlobal.openergy is the energy in % of the power bar shown in the O Power scene. It can be between 0 and 100 inclusive.
What can you add in?
You can program a way to have the "most powerful O-Power". Each activation of powers checks its level, and if it has an unknown level (i.e. not 1, 2 nor 3), the power is more beneficial than other. If you want to add a new O-Power, all you have to do is define an id in module OPowers as well as a name, description and cost, and modify the code.
I hope this is worth for you, and I would thank if you mention me in the credits. :D
I'm gonna give you some instructions to set up the 6th generation powers that you have. They have several functions: boost your team in battles, increase the gained money, speed up your egg hatching and pokemon growth... In the original games, using this consumes some "energy", which is restored when you close your DS and start walking.
Obviously, it's difficult to walk if you are playing your fan game in your desktop XD, so I created this code adapted to the Essentials scripts. This is how the O Powers works with this script:
- The O Power menu is in a button of Pokegear, and it is visible when you receive your first O Power level.
- The O Power data is stored in the global variable $PokemonGlobal (object of PokemonGlobalMetadata)
- The power energy is shown like a bar and fills up each 6400 steps (5% each 128)
- The effect of O Power dissapear in the specified minutes (3 by default) and a message is shown to let you know.
Here is the script you need. Put it above main to make it work.
Spoiler:
Code:
#=======================================
# O-Powers. Created by Samukomini
# Credit wanted but not required.
#=======================================
module OPowers
ATTACK = 0
DEFENSE = 1
CATCH = 2
HP_HEAL = 3
PP_HEAL = 4
REWARD = 5
CRITICAL = 6
HAPPINESS = 7
DISCOUNT = 8
ENCOUNTER = 9
REPEL = 10
INCUBATION = 11
EXP_GAIN = 12
IV = 13
def self.names
return ["Attack","Defense","Capture","HP Restore","PP Restore",
"Reward","Critical","Happiness","Discount","Encounter",
"Repel","Incubation","Experience Points","Individual Values"]
end
def self.descriptions
return [
"Boost the attack of your leading Pok?mon in the next battle.",
"Boost the attack of your leading Pok?mon in the next battle.",
"Raise the probability of catching a Pok?mon.",
"Restore your team health.",
"Restore your team moves PPs.",
"Raise the money you steal the trainers you win.",
"Raise the critical hit ratio in battle.",
"Boost the happiness your Pok?mon win.",
"Cut the prices on products in Pok?mon Mart.",
"Raise the probability of encountering a wild Pok?mon.",
"Reduce the probability of encountering a wild Pok?mon.",
"Speed up your egg hatching.",
"Boost the experience points earned by your Pok?mon.",
"Wild Pok?mon will boost their Individual Values."
]
end
def self.costs(level) # Over 100
case level
when 1
return [10,10,20,10,20,15,15,15,20,10,15,20,25,25]
when 2
return [20,20,30,20,30,30,25,25,40,20,30,30,35,35]
when 3
return [30,30,40,30,40,45,40,35,60,30,40,40,50,50]
end
raise ArgumentError.new("Undefined cost for level: #{level}")
end
def self.instant?(power)
return [ATTACK,DEFENSE,HP_HEAL,PP_HEAL].include?(getID(self,power))
end
def self.length; self.constants.length; end
def self.getByName(name)
for i in 0...length
return i if names[i] == name
end
return -1
end
end
class PokemonGlobalMetadata
attr_reader :oplevels
attr_accessor :opower_data
attr_reader :openergy
alias old_initialize initialize
def initialize
old_initialize
@oplevels = []
@opower_data = Array.new(OPowers.length) { nil }
@openergy = 100
end
def opLevelUp(op,level=nil)
if @oplevels.empty?
@oplevels = Array.new(OPowers.length) {0}
end
op = getID(OPowers,op)
if level
@oplevels[op] = level
else
@oplevels[op] += 1
end
end
def openergy=(val)
@openergy = val
@openergy = 0 if @openergy < 0
@openergy = 100 if @openergy > 100
end
end
class Scene_Map
alias op_update update
def update
op_update
update_opower
end
def update_opower
for i in 0...$PokemonGlobal.opower_data.length
data = $PokemonGlobal.opower_data[i]
next if OPowers.instant?(i) || !data
if Time.now.to_i > data[1].to_i + data[2] # Time expired
Kernel.pbMessage(_INTL("The effect of {1} O-Power finished.",OPowers.names[i]))
$PokemonGlobal.opower_data[i] = nil
end
end
end
end
## Launch a power. Return if it has been succesfully launched.
def pbLaunchOPower(opower,level,consume=true,time=3,showmessage=true,effects=true)
opower = getID(OPowers,opower)
if consume || ($DEBUG && Input.press?(Input::CTRL))
if OPowers.costs(level)[opower] > $PokemonGlobal.openergy # Not enough energy
Kernel.pbMessage("There isn't enough energy to launch this power.") if showmessage
return false
end
$PokemonGlobal.openergy -= OPowers.costs(level)[opower]
end
if effects
pbSEPlay("o_power")
pbFadeOutIn2(255,255,255) {yield if block_given?}
end
Kernel.pbMessage(_INTL("You have activated {1} O-Power - Level {2}.",
OPowers.names[opower],level.to_s)) if showmessage
$PokemonGlobal.opower_data[opower] = [level,Time.now,(time*60).floor] # Time not needed for instant O-Powers
## Repel replaces Encounter and vice versa
if isConst?(opower,OPowers,:ENCOUNTER)
$PokemonGlobal.opower_data[OPowers::REPEL] = nil
elsif isConst?(opower,OPowers,:REPEL)
$PokemonGlobal.opower_data[OPowers::ENCOUNTER] = nil
end
if OPowers.instant?(opower)
if isConst?(opower,OPowers,:HP_HEAL)
case level
when 1; prop = 1.0/3.0
when 2; prop = 0.5
when 3; prop = 2.0/3.0
else; prop = 1
end
for i in $Trainer.party
pbItemRestoreHP(i,(i.totalhp*prop).round)
end
$PokemonGlobal.opower_data[opower] = nil
elsif isConst?(opower,OPowers,:PP_HEAL)
case level
when 1; restore = 5
when 2; restore = 10
when 3; restore = 15
else; restore = 40
end
for i in $Trainer.party
for j in 0...i.moves.length
pbRestorePP(i,j,restore)
end
end
$PokemonGlobal.opower_data[opower] = nil
end
end
end
Events.onStepTaken += proc {
if $PokemonGlobal.happinessSteps==0
# Done each 128 steps. See this Event in PField_Field section.
$PokemonGlobal.openergy += 5
# O Power energy would be full restored in 6400 steps
end
}
Events.onWildPokemonCreate += proc {|s,e|
pokemon = e[0]
o = $PokemonGlobal.opower_data[OPowers::IV]
if o
case o[0]
when 1; mod = rand(2) + 1
when 2; mod = rand(3) + 2
when 3; mod = rand(4) + 3
else; mod = 6
end
ivs = randomAry(mod,pokemon.iv.length) # Random indexes of modifying ivs
for i in ivs
pokemon.iv[i] = 31
end
pokemon.calcStats
end
}
class Scene_OPowers
def start
# => Prepare
@sprites = {}
@levels = $PokemonGlobal.oplevels.clone
# Indexes of the own O Powers (non-leveled 0)
@ownops = Array.new(OPowers.length) { |i| next i }
for i in [email protected]
if @levels[i] == 0
@ownops[i] = nil
end
end
@levels.delete(0); @ownops.compact!
# => # SPRITES
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height); @viewport.z=99999
@sprites[:list] = Window_CommandPokemon.newEmpty(169,46,330,276,@viewport)#
#@sprites[:list].windowskin = nil
@sprites[:list].index = 0
@sprites[:list].z = 255
@sprites[:list].windowskin = nil
##
@sprites[:header] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Poderes O"),0,0,216,28,@viewport)
@sprites[:header].baseColor = Color.new(248,248,248) ##TODO
@sprites[:header].shadowColor = Color.new(0,0,0)
##
@sprites[:info] = Window_AdvancedTextPokemon.newWithSize("",
0,240,158,128,@viewport)
##
barpower = ($PokemonGlobal.openergy * 0.01 * 318).floor
@sprites[:bar] = IconSprite.new(178,336,@viewport)
@sprites[:bar].setBitmap("Graphics/Pictures/O Power/bar")
@sprites[:bar].src_rect = Rect.new(0,0,barpower,32)
@sprites[:bar].z = 255
##
@sprites[:textwindow] = Window_UnformattedTextPokemon.new("")
@sprites[:textwindow].x = 0
@sprites[:textwindow].y = 116
@sprites[:textwindow].width = 158
@sprites[:textwindow].height = 252
@sprites[:textwindow].viewport = @viewport
@sprites[:textwindow].windowskin = nil
## LISTA ##
commands = []
for i in [email protected]
commands.push(_INTL("{1} - Lvl {2}",OPowers.names[@ownops[i]],@levels[i]))
end
commands.push("Exit")
addBackgroundPlane(@sprites,:bg,"O Power/bg",@viewport)
@sprites[:list].commands = commands
pbFadeInAndShow(@sprites)
Graphics.transition
loop do # Update loop
Graphics.update
Input.update
update
update_text
pbUpdateSpriteHash(@sprites)
break if @break
end
pbFadeOutAndHide(@sprites)
# Disposes the windows
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
def update
if Input.trigger?(Input::B) # Back
pbPlayCancelSE()
@break = true
return
elsif Input.trigger?(Input::C)
index = @sprites[:list].index
if index == @ownops.length # Index of exit (last command)
pbPlayCancelSE()
@break = true
return
end
selected = @ownops[index] # O Power id selected
if $PokemonGlobal.oplevels[selected] == 1
if Kernel.pbConfirmMessage(_INTL("Activate {1} O-Power?",@sprites[:list].commands[index]))
pbLaunchOPower(selected,1)
end
else
commands = []
for i in 1..$PokemonGlobal.oplevels[selected]
commands.push(_INTL("Level {1} ({2}%)",i.to_s,OPowers.costs(i)[selected].to_s))
end
commands.push("Exit")
cmd = Kernel.pbMessage(_INTL("Choose a level."),commands,commands.length)
if cmd < commands.length-1 # Not back command
if Kernel.pbConfirmMessage(_INTL("Activate {1} O-Power - level {2}?",
OPowers.names[selected],cmd+1))
# Se lanza el poder O
pbLaunchOPower(selected,cmd+1) {update_bar}
end
end
#$scene = Scene_ConfirmOPower.new(selected)
end
end
end
def update_text
selected = getID(OPowers,@ownops[@sprites[:list].index]) # O Power id selected
if !selected
# Back tag
@sprites[:textwindow].text = _INTL("Back to the main menu.")
else
# O Power descriptions
@sprites[:textwindow].text = OPowers.descriptions[selected] # Put descriptions
end
end
def update_bar
barpower = ($PokemonGlobal.openergy * 0.01 * 318).floor
@sprites[:bar].src_rect.set(0,0,barpower,32)
end
end
def pbFadeOutIn2(red,green,blue)
col = Color.new(red,green,blue)
viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
viewport.z = 99999
for j in 0..17
col.set(red,green,blue,j*15)
viewport.color = col
Graphics.update
Input.update
end
pbPushFade
begin
yield if block_given?
ensure
pbPopFade
for j in 0..17
col.set(red,green,blue,(17-j)*15)
viewport.color=col
Graphics.update
Input.update
end
viewport.dispose
end
end
Now you need to make some changes in your scripts. I recommend you to put comment to point out that you have modified the script, if there was any error.
Attack and defense
I have modified this O Power: Attack makes the leading Pok?mon raise its attack and special attack when it is called out. Defense does it for defense and special defense. To set up this, find in PokeBattle_Battle, in def pbStartBattleCore (line 2515) pbOnActiveAll and put this below it:
Spoiler:
Code:
#pbOnActiveAll
o = $PokemonGlobal.opower_data[OPowers::ATTACK]
if o && @internalbattle #!#OPOWER ATTACK
for i in [email protected]
if pbOwnedByPlayer?(i)
@battlers[i].pbIncreaseStatWithCause(
PBStats::ATTACK,o[0]*2,@battlers[i],"O-Power #{OPowers.names[OPowers::ATTACK]}")
@battlers[i].pbIncreaseStatWithCause(
PBStats::SPATK,o[0]*2,@battlers[i],"O-Power #{OPowers.names[OPowers::ATTACK]}")
end
end
$PokemonGlobal.opower_data[OPowers::ATTACK] = nil
end
o = $PokemonGlobal.opower_data[OPowers::DEFENSE]
if o && @internalbattle #!#OPOWER DEFENSE
for i in [email protected]
if pbOwnedByPlayer?(i)
@battlers[i].pbIncreaseStatWithCause(
PBStats::DEFENSE,o[0]*2,@battlers[i],"O-Power #{OPowers.names[OPowers::DEFENSE]}")
@battlers[i].pbIncreaseStatWithCause(
PBStats::SPDEF,o[0]*2,@battlers[i],"O-Power #{OPowers.names[OPowers::DEFENSE]}")
end
end
$PokemonGlobal.opower_data[OPowers::DEFENSE] = nil
end
#@turncount=0
Again, find in PokeBattle_Battle, def pbThrowPokeball and put this above shakes=0 (line 124).
Spoiler:
Code:
#end
o = $PokemonGlobal.opower_data[OPowers::CATCH]
if o && @internalbattle #!#OPOWER CATCH
case o[0]
when 1; c = (c*1.25).floor
when 2; c = (c*4.0/3).floor
when 3; c = (c*1.5).floor
else; c *= 2
end
end
#shakes=0; critical=false
In the same class, find in def pbEndOfBattle (line 3939) and put this below tmoney*=2 if @doublemoney.
Spoiler:
Code:
# tmoney*=2 if @doublemoney
if o = $PokemonGlobal.opower_data[OPowers::REWARD] #!#OPOWER REWARD
case o[0] #!# Level
when 1; tmoney = (tmoney*1.5).floor
when 2; tmoney *= 2
when 3; tmoney *= 3
else; tmoney *= 5
end
end
Now, in PokeBattle_Move, in def pbIsCritical? find c+=1 if attacker.hasWorkingItem(...) (line 582) and put this below it:
Spoiler:
Code:
# c+=1 if attacker.hasWorkingItem(:SCOPELENS)
o = $PokemonGlobal.opower_data[OPowers::CRITICAL] #!#OPOWER
if o && @battle.internalbattle && #!# IF not an organized battle.
@battle.pbOwnedByPlayer?(attacker.index) #!# If user is the player.
c += o[0]>3 ? 3 : o[0] # Un aumento de cr?ticos por cada nivel de Poder O
end
# c=4 if c>4
Go to PokeBattle_Pokemon to def changeHappiness and before @happiness+=gain (line 837) put this:
Spoiler:
Code:
# end
o = $PokemonGlobal.opower_data[OPowers::HAPPINESS] #!#OPOWER HAPPINESS
if o
case o[0]
when 1; gain *= 1.5
when 2; gain *= 2
when 3; gain *= 2.5
else; gain *= 3
end
gain = gain.round
end
# @happiness+=gain
Discount
Go to PScreen_Mart, def pbPokemonMart (line 792). Replace everything that is before stock.compact! and put this (make sure you also change your own methods!):
Spoiler:
Code:
o = $PokemonGlobal.opower_data[OPowers::DISCOUNT] #!#OPOWER DISCOUNT
for i in 0...stock.length
stock[i]=getID(PBItems,stock[i]) if !stock[i].is_a?(Integer)
if !stock[i] || stock[i]==0 ||
(pbIsImportantItem?(stock[i]) && $PokemonBag.pbQuantity(stock[i])>0)
stock[i]=nil
end
if o #!#
case o[0] #Level
when 1; prop = 0.9
when 2; prop = 0.75
else; prop = 0.5
end
$game_temp.mart_prices[stock[i]]=[-1,-1] if !$game_temp.mart_prices[stock[i]]
$game_temp.mart_prices[stock[i]][0]=($ItemData[stock[i]][ITEMPRICE]*prop).round
end
end
# stock.compact!
Go to PField_Encounters, def pbGenerateEncounter, line 321. Put above return nil if rand ...:
Spoiler:
Code:
o = $PokemonGlobal.opower_data[OPowers::ENCOUNTER] #!#OPOWERS ENCOUNTER REPEL
r = $PokemonGlobal.opower_data[OPowers::REPEL]
if o || r
mod = nil
case o ? o[0] : r[0]
when 1; mod = 0.9
when 2; mod = 0.75
when 3; mod = 0.5
end
if mod
if o
encount/=mod
else
encount*=mod
end
else
encount = o ? -1 : 180*16 + 1
end
end
# return nil if rand(180*16)>=encount
I have change this proc because it was inadaptable to these scripts. The effect is exactly the same, but more flexible to changes. In PScreen_EggHatching, line 205, comment by putting a =begin ... =end block (like commenting with '#') starting in the method Events.onStepTaken+=proc {|sender,e and add out of the block this:
Spoiler:
Code:
Events.onStepTaken += proc {
next if !$Trainer
minus = 1 # The number that the Egg Steps will be taken
for i in $Trainer.party
if isConst?(i.ability,PBAbilities,:FLAMEBODY) ||
isConst?(i.ability,PBAbilities,:MAGMAARMOR)
minus += 1
break
end
end
o = $PokemonGlobal.opower_data[OPowers::INCUBATION] rescue nil #!#OPOWERS
if o
case o[0] # Level
when 1; minus = 1.25
when 2; minus = 1.5
when 3; minus = 2
else; minus = 3
end
end
for egg in $Trainer.party
next if egg.eggsteps <= 0 # Not an egg
egg.eggsteps -= minus
if egg.eggsteps <= 0
egg.eggsteps = 0
pbHatch(egg)
end
end
}
Experience gain
Go back to PokeBattle_Battle section in def pbGainExpOne. Below isConst?(thispoke.itemInitial,PBItems,:LUCKYEGG) (line 1930) put this code:
Spoiler:
Code:
#exp=(exp*3/2).floor if isConst?(thispoke.item,PBItems,:LUCKYEGG) ||
# isConst?(thispoke.itemInitial,PBItems,:LUCKYEGG)
o = $PokemonGlobal.opower_data[OPowers::EXP_GAIN] #!# OPOWER EXP
if o
case o[0] # Level
when 1; exp *= 1.2
when 2; exp *= 1.5
when 3; exp *= 2
else; exp *= 3
end
exp = exp.floor
end
# growthrate=thispoke.growthrate
Now you have to put the button in the Pok?Gear.
Add this line in the section PScreen_Pokegear (def pbStartScreen, line 120) below [I@cmdJukebox=-1[/I]
Code:
cmdOPower=-1 #!#OP
Code:
commands[cmdOPowers = commands.length] = ["o-powers",_INTL("O-Powers")] if !$PokemonGlobal.oplevels.empty? #!#OP
Code:
elsif cmdOPowers>=0 && cmd==cmdOPowers #!#OPOWERS
pbPlayDecisionSE()
Scene_OPowers.new.start
# end
And Now the code is set! All you have to do is activate O-Powers in the adventure by using this code:n
Code:
$PokemonGlobal.opLevelUp(OPowers::X,level)
The attribute $PokemonGlobal.oplevels is an Array of the current level of each O Power id. If it is empty, the PokeGear won't show the O Power button. $PokemonGlobal.opower_data Array stores the current working O Power wich also relates each O Power id with the launched O Power ([level,launch time,duration] or nil if none). $PokemonGlobal.openergy is the energy in % of the power bar shown in the O Power scene. It can be between 0 and 100 inclusive.
What can you add in?
You can program a way to have the "most powerful O-Power". Each activation of powers checks its level, and if it has an unknown level (i.e. not 1, 2 nor 3), the power is more beneficial than other. If you want to add a new O-Power, all you have to do is define an id in module OPowers as well as a name, description and cost, and modify the code.
I hope this is worth for you, and I would thank if you mention me in the credits. :D
Attachments
Last edited: