Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0
Razor

RGSS and RMXP

Question

Ok, so I have a specific problem and a general question.

 

I'm going to take a look at the different tutorials here in the tutorials subforum, but I wanted to ask if there is a tutorial that involves you making a game as you move through the tutorial? The reason I have trouble with most tutorials is that they teach me how to do some things but I have difficulty applying it. Anyway, if there's a tutorial like that, please direct me to it. If there isn't one, then maybe I threw out an idea someone can use.

 

Now for the specific problem:

 

We're working on a version of pokemon essentials. The problem is that when you defeat an enemy pokemon, while every pokemon that fights against the enemy will gain exp and increase in levels, only the pokemon that you have out when you defeat the enemy will learn new moves. The pokemon in your party can still level up, but will not learn new moves. The problem appears to be that the code looks for the pokemon that is currently out, and ignores pokemon in the player's party.

 

Here's the code:

 

def pbLearnMove(pkmnIndex,move)  pokemon=@party1[pkmnIndex]  return if !pokemon  pkmnname=pokemon.name  battler=pbFindPlayerBattler(pkmnIndex)  movename=PBMoves.getName(move)  for i in 0..3   if pokemon.moves[i].id==move    return   end   if pokemon.moves[i].id==0    pokemon.moves[i]=PBMove.new(move)    battler.moves[i]=PokeBattle_Move.pbFromPBMove(self,pokemon.moves[i]) if battler    pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename))    return   end  end  loop do   pbDisplayPaused(_INTL("{1} is trying to learn {2}.",pkmnname,movename)) #Replaces current/total PP   pbDisplayPaused(_INTL("But {1} can't learn more than four moves.",pkmnname))   if pbDisplayConfirm(_INTL("Delete a move to make room for {1}?",movename))    pbDisplayPaused(_INTL("Which move should be forgotten?"))    forgetmove=@scene.pbForgetMove(pokemon,move)    if forgetmove >=0 	oldmovename=PBMoves.getName(pokemon.moves[forgetmove].id) 	pokemon.moves[forgetmove]=PBMove.new(move)#Replaces current/total PP 	battler.moves[forgetmove]=PokeBattle_Move.pbFromPBMove(self,pokemon.moves[forgetmove]) if battler 	pbDisplayPaused(_INTL("1,  2, and... ... ...")) 	pbDisplayPaused(_INTL("Poof!")) 	pbDisplayPaused(_INTL("{1} forgot {2}.",pkmnname,oldmovename)) 	pbDisplayPaused(_INTL("And...")) 	pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename)) 	return    elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename)) 	pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename)) 	return    end   elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename))    pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename))    return   end  end end  def pbGainEXP  return if !@internalbattle  successbegin=true  for i in 0..3 # Not ordered by priority   if !@doublebattle && pbIsDoubleBattler?(i)    @battlers[i].participants=[]    next   end   if pbIsOpposing?(i) && @battlers[i].participants.length>0 && @battlers[i].hp<=0    dexdata=pbOpenDexData    battlerSpecies=@battlers[i].species    # Current species, not original species; also using R/S base EXP    pbDexDataOffset(dexdata,battlerSpecies,17)    baseexp=dexdata.fgetb    level=@battlers[i].level    dexdata.close    # First count the number of participants    partic=0    expshare=0    for j in @battlers[i].participants 	@participants[j]=true # Add participant to global list    end    for j in @battlers[i].participants 	next if !@party1[j] || !pbIsOwner?(0,j) 	partic+=1 if @party1[j].hp>0 && !@party1[j].egg?    end    for j in 0..@party1.length-1 	next if !@party1[j] || !pbIsOwner?(0,j) 	expshare+=1 if @party1[j].hp>0 && !@party1[j].egg? &&            isConst?(@party1[j].item,PBItems,:EXPSHARE)    end    # Now calculate EXP for the participants    if partic>0 	if !@opponent && successbegin && pbAllFainted?(@party2)      @scene.pbWildBattleSuccess      successbegin=false 	end 	for j in 0..@party1.length-1      thispoke=@party1[j]      next if !@party1[j] || !pbIsOwner?(0,j)      ispartic=0      level=@battlers[i].level      haveexpshare=(isConst?(thispoke.item,PBItems,:EXPSHARE)) ? 1 : 0      for k in @battlers[i].participants   	ispartic=1 if k==j      end      if thispoke.hp>0 && !thispoke.egg?   	exp=0   	if expshare>0        exp=((level*baseexp/7).floor/2).floor        exp=(exp/partic).floor*ispartic+(exp/expshare).floor*haveexpshare   	elsif ispartic==1        exp=((level*baseexp/7).floor/partic).floor   	end   	isOutsider=(thispoke.trainerID!=self.pbPlayer.id || (thispoke.language!=0 && thispoke.language!=self.pbPlayer.language))   	exp=(exp*3/2).floor if @opponent   	exp=(exp*3/2).floor if isOutsider   	exp=(exp*3/2).floor if isConst?(thispoke.item,PBItems,:LUCKYEGG)   	growthrate=thispoke.growthrate   	newexp=PBExperience.pbAddExperience(thispoke.exp,exp,growthrate)   	exp=newexp-thispoke.exp;   	if exp > 0        if isOutsider 		pbDisplayPaused(_INTL("{1} gained a boosted\r\n{2} Exp. Points!",thispoke.name,exp))        else 		pbDisplayPaused(_INTL("{1} gained\r\n{2} Exp. Points!",thispoke.name,exp))        end        #Gain effort value points, using RS effort values        totalev=0        for k in 0..5 		totalev+=thispoke.ev[k]        end        dexdata=pbOpenDexData        pbDexDataOffset(dexdata,battlerSpecies,23)        for k in 0..5 		evgain=dexdata.fgetb 		if isConst?(thispoke.item,PBItems,:MACHOBRACE)          evgain*=2 		end 		if evgain>0          # Can't exceed overall limit          if totalev+evgain>510   		# Bug Fix: must use "-=" instead of "="   		evgain-=totalev+evgain-510          end          # Can't exceed stat limit          if thispoke.ev[k]+evgain>255   		# Bug Fix: must use "-=" instead of "="   		evgain-=thispoke.ev[k]+evgain-255          end          # Add EV gain          thispoke.ev[k]+=evgain          if thispoke.ev[k]>255   		print "Single-stat EV limit 255 exceeded.\r\nStat: #{k}  EV gain: #{evgain}  EVs: #{thispoke.ev.inspect}"   		thispoke.ev[k]=255          end          totalev+=evgain          if totalev>510   		print "EV limit 510 exceeded.\r\nTotal EVs: #{totalev} EV gain: #{evgain}  EVs: #{thispoke.ev.inspect}"          end 		end        end        newlevel=PBExperience.pbGetLevelFromExperience(newexp,growthrate)        tempexp=0        curlevel=thispoke.level        thisPokeSpecies=thispoke.species        if newlevel<curlevel 		debuginfo="#{thispoke.name}: #{thispoke.level}/#{newlevel} | #{thispoke.exp}/#{newexp} | gain: #{exp}" 		raise RuntimeError.new(          _INTL("The new level ({1}) is less than the Pokémon's\r\ncurrent level ({2}), which shouldn't happen.\r\n[Debug: {3}]",          newlevel,curlevel,debuginfo)) 		return        end        if thispoke.respond_to?("isShadow?") && thispoke.isShadow? 		thispoke.exp+=exp        else 		tempexp1=thispoke.exp 		tempexp2=0 		# Find battler 		battler=pbFindPlayerBattler(j) 		loop do          #EXP Bar animation          startexp=PBExperience.pbGetStartExperience(curlevel,growthrate)          endexp=PBExperience.pbGetStartExperience(curlevel+1,growthrate)          tempexp2=(endexp<newexp) ? endexp : newexp          thispoke.exp=tempexp2          @scene.pbEXPBar(thispoke,battler,startexp,endexp,tempexp1,tempexp2)          tempexp1=tempexp2          curlevel+=1          break if curlevel>newlevel          oldtotalhp=thispoke.totalhp          oldattack=thispoke.attack          olddefense=thispoke.defense          oldspeed=thispoke.speed          oldspatk=thispoke.spatk          oldspdef=thispoke.spdef          thispoke.calcStats          battler.pbUpdate if battler          @scene.pbRefresh          if battler.pokemon && @internalbattle   		battler.pokemon.happiness+=2   		battler.pokemon.happiness=255 if battler.pokemon.happiness>255          end          pbDisplayPaused(_INTL("{1} grew to Level {2}!",thispoke.name,curlevel))          @scene.pbLevelUp(thispoke,battler,oldtotalhp,oldattack,              olddefense,oldspeed,oldspatk,oldspdef)          # Finding all moves learned at this level          atkdata=pbRgssOpen("Data/attacksRS.dat","rb")          offset=atkdata.getOffset(thisPokeSpecies-1)          length=atkdata.getLength(thisPokeSpecies-1)>>1          atkdata.pos=offset          for k in 0..length-1   		atklevel=atkdata.fgetw   		move=atkdata.fgetw   		if atklevel==thispoke.level            # Learned a new move            pbLearnMove(j,move)   		end          end          atkdata.close 		end        end   	end      end 	end    end    # Now clear the participants array    @battlers[i].participants=[]   end  end en

Edited by Razor

Share this post


Link to post
Share on other sites

15 answers to this question

Recommended Posts

  • 0

I will take a look at it and see if I can figure it out! I have to split it into different lines first though, your post formatted the script funny.

Share this post


Link to post
Share on other sites
  • 0

Let's see if I can make it look better:

 

def pbLearnMove(pkmnIndex,move)

pokemon=@party1[pkmnIndex]

return if !pokemon

pkmnname=pokemon.name

battler=pbFindPlayerBattler(pkmnIndex)

movename=PBMoves.getName(move)

for i in 0..3

if pokemon.moves.id==move

return

end

if pokemon.moves.id==0

pokemon.moves=PBMove.new(move)

battler.moves=PokeBattle_Move.pbFromPBMove(self,pokemon.moves) if battler

pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename))

return

end

end

loop do

pbDisplayPaused(_INTL("{1} is trying to learn {2}.",pkmnname,movename)) #Replaces current/total PP

pbDisplayPaused(_INTL("But {1} can't learn more than four moves.",pkmnname))

if pbDisplayConfirm(_INTL("Delete a move to make room for {1}?",movename))

pbDisplayPaused(_INTL("Which move should be forgotten?"))

forgetmove=@scene.pbForgetMove(pokemon,move)

if forgetmove >=0

oldmovename=PBMoves.getName(pokemon.moves[forgetmove].id)

pokemon.moves[forgetmove]=PBMove.new(move)#Replaces current/total PP

battler.moves[forgetmove]=PokeBattle_Move.pbFromPBMove(self,pokemon.moves[forgetmove]) if battler

pbDisplayPaused(_INTL("1, 2, and... ... ..."))

pbDisplayPaused(_INTL("Poof!"))

pbDisplayPaused(_INTL("{1} forgot {2}.",pkmnname,oldmovename))

pbDisplayPaused(_INTL("And..."))

pbDisplayPaused(_INTL("{1} learned {2}!",pkmnname,movename))

return

elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename))

pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename))

return

end

elsif pbDisplayConfirm(_INTL("Should {1} stop learning {2}?",pkmnname,movename))

pbDisplayPaused(_INTL("{1} did not learn {2}.",pkmnname,movename))

return

end

end

end

 

def pbGainEXP

return if !@internalbattle

successbegin=true

for i in 0..3 # Not ordered by priority

if !@doublebattle && pbIsDoubleBattler?(i)

@battlers.participants=[]

next

end

if pbIsOpposing?(i) && @battlers.participants.length>0 && @battlers.hp<=0

dexdata=pbOpenDexData

battlerSpecies=@battlers.species

# Current species, not original species; also using R/S base EXP

pbDexDataOffset(dexdata,battlerSpecies,17)

baseexp=dexdata.fgetb

level=@battlers.level

dexdata.close

# First count the number of participants

partic=0

expshare=0

for j in @battlers.participants

@participants[j]=true # Add participant to global list

end

for j in @battlers.participants

next if !@party1[j] || !pbIsOwner?(0,j)

partic+=1 if @party1[j].hp>0 && !@party1[j].egg?

end

for j in 0..@party1.length-1

next if !@party1[j] || !pbIsOwner?(0,j)

expshare+=1 if @party1[j].hp>0 && !@party1[j].egg? &&

isConst?(@party1[j].item,PBItems,:EXPSHARE)

end

# Now calculate EXP for the participants

if partic>0

if !@opponent && successbegin && pbAllFainted?(@party2)

@scene.pbWildBattleSuccess

successbegin=false

end

for j in 0..@party1.length-1

thispoke=@party1[j]

next if !@party1[j] || !pbIsOwner?(0,j)

ispartic=0

level=@battlers.level

haveexpshare=(isConst?(thispoke.item,PBItems,:EXPSHARE)) ? 1 : 0

for k in @battlers.participants

ispartic=1 if k==j

end

if thispoke.hp>0 && !thispoke.egg?

exp=0

if expshare>0

exp=((level*baseexp/7).floor/2).floor

exp=(exp/partic).floor*ispartic+(exp/expshare).floor*haveexpshare

elsif ispartic==1

exp=((level*baseexp/7).floor/partic).floor

end

isOutsider=(thispoke.trainerID!=self.pbPlayer.id || (thispoke.language!=0 && thispoke.language!=self.pbPlayer.language))

exp=(exp*3/2).floor if @opponent

exp=(exp*3/2).floor if isOutsider

exp=(exp*3/2).floor if isConst?(thispoke.item,PBItems,:LUCKYEGG)

growthrate=thispoke.growthrate

newexp=PBExperience.pbAddExperience(thispoke.exp,exp,growthrate)

exp=newexp-thispoke.exp;

if exp > 0

if isOutsider

pbDisplayPaused(_INTL("{1} gained a boosted\r\n{2} Exp. Points!",thispoke.name,exp))

else

pbDisplayPaused(_INTL("{1} gained\r\n{2} Exp. Points!",thispoke.name,exp))

end

#Gain effort value points, using RS effort values

totalev=0

for k in 0..5

totalev+=thispoke.ev[k]

end

dexdata=pbOpenDexData

pbDexDataOffset(dexdata,battlerSpecies,23)

for k in 0..5

evgain=dexdata.fgetb

if isConst?(thispoke.item,PBItems,:MACHOBRACE)

evgain*=2

end

if evgain>0

# Can't exceed overall limit

if totalev+evgain>510

# Bug Fix: must use "-=" instead of "="

evgain-=totalev+evgain-510

end

# Can't exceed stat limit

if thispoke.ev[k]+evgain>255

# Bug Fix: must use "-=" instead of "="

evgain-=thispoke.ev[k]+evgain-255

end

# Add EV gain

thispoke.ev[k]+=evgain

if thispoke.ev[k]>255

print "Single-stat EV limit 255 exceeded.\r\nStat: #{k} EV gain: #{evgain} EVs: #{thispoke.ev.inspect}"

thispoke.ev[k]=255

end

totalev+=evgain

if totalev>510

print "EV limit 510 exceeded.\r\nTotal EVs: #{totalev} EV gain: #{evgain} EVs: #{thispoke.ev.inspect}"

end

end

end

newlevel=PBExperience.pbGetLevelFromExperience(newexp,growthrate)

tempexp=0

curlevel=thispoke.level

thisPokeSpecies=thispoke.species

if newlevel<curlevel

debuginfo="#{thispoke.name}: #{thispoke.level}/#{newlevel} | #{thispoke.exp}/#{newexp} | gain: #{exp}"

raise RuntimeError.new(

_INTL("The new level ({1}) is less than the Pokémon's\r\ncurrent level ({2}), which shouldn't happen.\r\n[Debug: {3}]",

newlevel,curlevel,debuginfo))

return

end

if thispoke.respond_to?("isShadow?") && thispoke.isShadow?

thispoke.exp+=exp

else

tempexp1=thispoke.exp

tempexp2=0

# Find battler

battler=pbFindPlayerBattler(j)

loop do

#EXP Bar animation

startexp=PBExperience.pbGetStartExperience(curlevel,growthrate)

endexp=PBExperience.pbGetStartExperience(curlevel+1,growthrate)

tempexp2=(endexp<newexp) ? endexp : newexp

thispoke.exp=tempexp2

@scene.pbEXPBar(thispoke,battler,startexp,endexp,tempexp1,tempexp2)

tempexp1=tempexp2

curlevel+=1

break if curlevel>newlevel

oldtotalhp=thispoke.totalhp

oldattack=thispoke.attack

olddefense=thispoke.defense

oldspeed=thispoke.speed

oldspatk=thispoke.spatk

oldspdef=thispoke.spdef

thispoke.calcStats

battler.pbUpdate if battler

@scene.pbRefresh

if battler.pokemon && @internalbattle

battler.pokemon.happiness+=2

battler.pokemon.happiness=255 if battler.pokemon.happiness>255

end

pbDisplayPaused(_INTL("{1} grew to Level {2}!",thispoke.name,curlevel))

@scene.pbLevelUp(thispoke,battler,oldtotalhp,oldattack,

olddefense,oldspeed,oldspatk,oldspdef)

# Finding all moves learned at this level

atkdata=pbRgssOpen("Data/attacksRS.dat","rb")

offset=atkdata.getOffset(thisPokeSpecies-1)

length=atkdata.getLength(thisPokeSpecies-1)>>1

atkdata.pos=offset

for k in 0..length-1

atklevel=atkdata.fgetw

move=atkdata.fgetw

if atklevel==thispoke.level

# Learned a new move

pbLearnMove(j,move)

end

end

atkdata.close

end

end

end

end

end

end

# Now clear the participants array

@battlers.participants=[]

end

end

end

Share this post


Link to post
Share on other sites
  • 0

Okay I *may* know what the issue is.

first I have a question...

does

for k in @battlers.participants
 ispartic=1 if k==j
end

 

ispartic mean they pokemon was in the battle?

 

and another question, are all the pokemon learning skills? or just the ones outside of battle?

 

because (if I am correct)

 

if atklevel==thispoke.level && ispartic == 1
 # Learned a new move
 pbLearnMove(j,move)
end

 

HOWEVER, i am not sure if the original statement will work...

because the original for loop is:

for j in 0..@party1.length-1

so j iterates from 0..1..2...3..@party1.length-1 (or however many pokemon are in the party i guess)

then you have

for k in @battlers.participants
 ispartic=1 if k==j
end

which iterates through every @battlers.participants, so each time k == @battlers.participants[0...@battlers.participants.size] so if you compare a fixednumber to an object, it will always return false. you would probably need to have:

ispartic=1 if k==@party1[j]

so ispartic actually becomes 1 if one of the party members were participating.

 

I could have read the code wrong, but that's what I got out of it, i hope this helps

Share this post


Link to post
Share on other sites
  • 0

The problem is that only the pokemon that is selected at the end of the battle will learn new skills.

 

All of the pokemon in the fight will gain experience, but only the one that is out at the end will learn any new skills.

 

So, let's say I have Pikachu and Charmander. Let's say Pikachu is level 12, and learns quick attack at level 13. Charmander is level 9, and will learn smoke screen at level 10.

 

I fight in a battle and choose Pikachu first. Then, during the middle of the fight, I switch to Charmander and defeat the enemy. Let's say both pokemon received enough experience to level up.

 

Charmander hits level 10 and learns smoke screen. Pikachu hits level 13, but does not learn quick attack.

Edited by Razor

Share this post


Link to post
Share on other sites
  • 0

oohhhhh! What you'll have to do is create a variable that holds the information of the "currently" selected pokemon, and changes everytime a new pokemon is selected. Then when you

if atklevel==thispoke.level && thispoke == current_pokemon
 # Learned a new move
 pbLearnMove(j,move)
end

 

or something like that, just check if thispoke is equal to the currently selected pokemon (which would end up being the last selected pokemon before the battle ended

Share this post


Link to post
Share on other sites
  • 0

oohhhhh! What you'll have to do is create a variable that holds the information of the "currently" selected pokemon, and changes everytime a new pokemon is selected. Then when you

if atklevel==thispoke.level && thispoke == current_pokemon
 # Learned a new move
 pbLearnMove(j,move)
end

 

or something like that, just check if thispoke is equal to the currently selected pokemon (which would end up being the last selected pokemon before the battle ended

 

Correct me if I'm wrong, but this doesn't seem like it would solve the problem.

 

I believe what we need is something that will check the player's party for pokemon that participated in the fight that haven't feinted and will check to see if they have hit a level where they would learn a new move.

 

Also, there is an item called the "exp share", which allows a pokemon to gain experience from battles even if it does not participate. So, actually, the code needs to look for any pokemon that gained experience from the fight, regardless of whether or not they participated.

 

Since feinted pokemon don't gain experience, I think that would work. I would have done it already but I am simply not familiar enough with the syntax of Ruby to know how to pull it off.

Edited by Razor

Share this post


Link to post
Share on other sites
  • 0

Hmm...so do all the pokemon that fight in battle can learn moves? I may have misunderstood you...I thought it was the last pokemon that fought in battle only learned moves.

 

EDIT: From what I understand, only pokemon that have fought in battle, not fainted and gained a level to where they learn a move? If so, it seems "if atklevel==thispoke.level" checks if the pokemon is the right level, so from here you would just need some kind of array that each time a pokemon is brought into battle, they are added to the array ( array.push(object) will add the pokemon to the list) so something like

 if atklevel == thispoke.level && battle_pokemon.include?(thispoke) && thispoke.hp > 0
# Array.include?(object) returns true, if any instance of that object is included in the array, 
# and thispoke.hp > 0 (change hp to whatever represents the pokemon's health) 
# checks if the pokemon is alive

Edited by kellessdee

Share this post


Link to post
Share on other sites
  • 0

Hmm...so do all the pokemon that fight in battle can learn moves? I may have misunderstood you...I thought it was the last pokemon that fought in battle only learned moves.

 

EDIT: From what I understand, only pokemon that have fought in battle, not fainted and gained a level to where they learn a move? If so, it seems "if atklevel==thispoke.level" checks if the pokemon is the right level, so from here you would just need some kind of array that each time a pokemon is brought into battle, they are added to the array ( array.push(object) will add the pokemon to the list) so something like

 if atklevel == thispoke.level && battle_pokemon.include?(thispoke) && thispoke.hp > 0

# Array.include?(object) returns true, if any instance of that object is included in the array, and #thispoke.hp > 0 (change hp to whatever represents the pokemon's health) checks if the pokemon is alive[/code

 

Right now only the last pokemon to fight can learn new moves. This is the problem we are trying to correct. We [i]want[/i] every pokemon that has participated in the battle to be able to learn new moves, assuming they received enough exp to hit a level where they would normally learn a new move.

Edited by Razor

Share this post


Link to post
Share on other sites
  • 0

OH I totally misunderstood your issue from the beginning! I'm sorry! Well first off (I am sorry I am unsure EXACTLY what each variable holds) but do you have an array that holds the data for every pokemon that fought in battle? If so, just run either a for loop or .each loop

# for loop
for pokemon in battling_pokemon_array
 next if pokemon.hp <= 0 # if pokemon has fainted, skip to the next pokemon
 # Put your code for adding exp + learning moves as normal, except for pokemon (local variable defined in the for loop)
end

# each loop
battling_pokemon_array.each {|pokemon|
 next if pokemon.hp <= 0
 # add exp + moves
}

 

Each loops are very useful loops (that essentially work exactly like for loops) except were more designed to apply a block of code to each element of an array, the syntax is Array.each {|local_variable| code... } however you can also apply each loops to a range of numbers like (0..5).each {|i| code } which is like saying for i in 0..5 code end. You can also use Array.each_index {|i| code } which will go through each index of the array, and store the index in i rather than the contents...

Hope this helps!

 

EDIT: battling_pokemon_array would be the array that holds the data for each pokemon that fought in battle..if you don't already have one you can make one, and everytime the player brings a pokemon into battle call

battling_pokemon_array.push(pokemon) if !battling_pokemon_array.include?(pokemon)
# if the pokemon isn't already in the array, add it

Edited by kellessdee

Share this post


Link to post
Share on other sites
  • 0

I really wish I understood this better. I'm not sure exactly what to change and where to put everything.

 

Also, the more I think about it, the more I realize it's not so much whether the pokemon participated in the battle, but whether or not they gained experience.

 

There's an item called the exp share and if a pokemon holds that, it will gain exp even if it is not in battle. So we need the code to look for all pokemon that gained exp and see if any of them reached a level where they would normally learn a new move.

 

Here's the code for experience:

 

def pbGainEXP
return if !@internalbattle
successbegin=true
for i in 0..3 # Not ordered by priority
 if !@doublebattle && pbIsDoubleBattler?(i)
  @battlers[i].participants=[]
  next
 end
 if pbIsOpposing?(i) && @battlers[i].participants.length>0 && @battlers[i].hp<=0
  dexdata=pbOpenDexData
  battlerSpecies=@battlers[i].species
  # Current species, not original species; also using R/S base EXP
  pbDexDataOffset(dexdata,battlerSpecies,17)
  baseexp=dexdata.fgetb
  level=@battlers[i].level
  dexdata.close
  # First count the number of participants
  partic=0
  expshare=0
  for j in @battlers[i].participants
@participants[j]=true # Add participant to global list
  end
  for j in @battlers[i].participants
next if !@party1[j] || !pbIsOwner?(0,j)
partic+=1 if @party1[j].hp>0 && !@party1[j].egg?
  end
  for j in 0..@party1.length-1
next if !@party1[j] || !pbIsOwner?(0,j)
expshare+=1 if @party1[j].hp>0 && !@party1[j].egg? && 
     	isConst?(@party1[j].item,PBItems,:EXPSHARE)
  end
  # Now calculate EXP for the participants
  if partic>0
if !@opponent && successbegin && pbAllFainted?(@party2)
	@scene.pbWildBattleSuccess
	successbegin=false
end
for j in 0..@party1.length-1
	thispoke=@party1[j]
	next if !@party1[j] || !pbIsOwner?(0,j)
	ispartic=0
	level=@battlers[i].level
	haveexpshare=(isConst?(thispoke.item,PBItems,:EXPSHARE)) ? 1 : 0
	for k in @battlers[i].participants
 	ispartic=1 if k==j
	end
	if thispoke.hp>0 && !thispoke.egg?
 	exp=0
 	if expshare>0
  	exp=((level*baseexp/7).floor/2).floor
  	exp=(exp/partic).floor*ispartic+(exp/expshare).floor*haveexpshare
 	elsif ispartic==1
  	exp=((level*baseexp/7).floor/partic).floor
 	end
 	isOutsider=(thispoke.trainerID!=self.pbPlayer.id || (thispoke.language!=0 && thispoke.language!=self.pbPlayer.language))
 	exp=(exp*3/2).floor if @opponent
 	exp=(exp*3/2).floor if isOutsider
 	exp=(exp*3/2).floor if isConst?(thispoke.item,PBItems,:LUCKYEGG)
 	growthrate=thispoke.growthrate
 	newexp=PBExperience.pbAddExperience(thispoke.exp,exp,growthrate)
 	exp=newexp-thispoke.exp;
 	if exp > 0
  	if isOutsider
   	pbDisplayPaused(_INTL("{1} gained a boosted\r\n{2} Exp. Points!",thispoke.name,exp))
  	else
   	pbDisplayPaused(_INTL("{1} gained\r\n{2} Exp. Points!",thispoke.name,exp))
  	end
  	#Gain effort value points, using RS effort values
  	totalev=0
  	for k in 0..5
   	totalev+=thispoke.ev[k]
  	end
  	dexdata=pbOpenDexData
  	pbDexDataOffset(dexdata,battlerSpecies,23)
  	for k in 0..5
   	evgain=dexdata.fgetb
   	if isConst?(thispoke.item,PBItems,:MACHOBRACE)
		evgain*=2
   	end
   	if evgain>0
		# Can't exceed overall limit
		if totalev+evgain>510
     	# Bug Fix: must use "-=" instead of "="
     	evgain-=totalev+evgain-510
		end
		# Can't exceed stat limit
		if thispoke.ev[k]+evgain>255
     	# Bug Fix: must use "-=" instead of "="
     	evgain-=thispoke.ev[k]+evgain-255
		end
		# Add EV gain
		thispoke.ev[k]+=evgain
		if thispoke.ev[k]>255
     	print "Single-stat EV limit 255 exceeded.\r\nStat: #{k}  EV gain: #{evgain}  EVs: #{thispoke.ev.inspect}"
     	thispoke.ev[k]=255
		end
		totalev+=evgain
		if totalev>510
     	print "EV limit 510 exceeded.\r\nTotal EVs: #{totalev} EV gain: #{evgain}  EVs: #{thispoke.ev.inspect}"
		end
   	end
  	end
  	newlevel=PBExperience.pbGetLevelFromExperience(newexp,growthrate)
  	tempexp=0
  	curlevel=thispoke.level
  	thisPokeSpecies=thispoke.species
  	if newlevel<curlevel
   	debuginfo="#{thispoke.name}: #{thispoke.level}/#{newlevel} | #{thispoke.exp}/#{newexp} | gain: #{exp}"
   	raise RuntimeError.new(
		_INTL("The new level ({1}) is less than the Pokémon's\r\ncurrent level ({2}), which shouldn't happen.\r\n[Debug: {3}]",
		newlevel,curlevel,debuginfo))
   	return
  	end
  	if thispoke.respond_to?("isShadow?") && thispoke.isShadow?
   	thispoke.exp+=exp
  	else
   	tempexp1=thispoke.exp
   	tempexp2=0
   	# Find battler
   	battler=pbFindPlayerBattler(j)
   	loop do
		#EXP Bar animation
		startexp=PBExperience.pbGetStartExperience(curlevel,growthrate)
		endexp=PBExperience.pbGetStartExperience(curlevel+1,growthrate)
		tempexp2=(endexp<newexp) ? endexp : newexp
		thispoke.exp=tempexp2
		@scene.pbEXPBar(thispoke,battler,startexp,endexp,tempexp1,tempexp2)
		tempexp1=tempexp2
		curlevel+=1
		break if curlevel>newlevel
		oldtotalhp=thispoke.totalhp
		oldattack=thispoke.attack
		olddefense=thispoke.defense
		oldspeed=thispoke.speed
		oldspatk=thispoke.spatk
		oldspdef=thispoke.spdef
		thispoke.calcStats
		battler.pbUpdate if battler
		@scene.pbRefresh
		if battler.pokemon && @internalbattle
     	battler.pokemon.happiness+=2
     	battler.pokemon.happiness=255 if battler.pokemon.happiness>255
		end
		pbDisplayPaused(_INTL("{1} grew to Level {2}!",thispoke.name,curlevel))
		@scene.pbLevelUp(thispoke,battler,oldtotalhp,oldattack,
			olddefense,oldspeed,oldspatk,oldspdef)
		# Finding all moves learned at this level
		atkdata=pbRgssOpen("Data/attacksRS.dat","rb")
		offset=atkdata.getOffset(thisPokeSpecies-1)
		length=atkdata.getLength(thisPokeSpecies-1)>>1
		atkdata.pos=offset
		for k in 0..length-1
     	atklevel=atkdata.fgetw
     	move=atkdata.fgetw
     	if atklevel==thispoke.level
  		# Learned a new move
  		pbLearnMove(j,move)
     	end
		end
		atkdata.close
   	end
  	end
 	end
	end
end
  end
  # Now clear the participants array
  @battlers[i].participants=[]
 end
end
end

Share this post


Link to post
Share on other sites
  • 0

So basically, you need the script to give each pokemon that isn't dead experience? Does this only happen if you have the certain item?

If you can tell me which variables are used to store the data for each pokemon in the party, I can probably help you out more.

I am not sure if I understand the code well enough...but basically, in pseudo code what You would need to do is

 

if player has exp share
 get entire party
else
 get pokemon who participated in battle
end

for every pokemon gotten
 if this pokemon has fainted
   next pokemon
 else
   add exp to this pokemon
   if this pokemon has gained a level
     if new move learned
       add new move
     end
   end
 end
end

 

I hope this helps you understand what you would need to do. If I understood your code a little bit better I may be able to help you more specifically.

however...wouldn't it be easier to make each pokemon an actor, so you could set their level + skills? then if they level up they will learn the skills, etc? That way you don't have to read out of a file to learn the moves... just a suggestion

Share this post


Link to post
Share on other sites
  • 0

So basically, you need the script to give each pokemon that isn't dead experience? Does this only happen if you have the certain item?

If you can tell me which variables are used to store the data for each pokemon in the party, I can probably help you out more.

I am not sure if I understand the code well enough...but basically, in pseudo code what You would need to do is

 

if player has exp share
 get entire party
else
 get pokemon who participated in battle
end

for every pokemon gotten
 if this pokemon has fainted
   next pokemon
 else
   add exp to this pokemon
   if this pokemon has gained a level
     if new move learned
       add new move
     end
   end
 end
end

 

I hope this helps you understand what you would need to do. If I understood your code a little bit better I may be able to help you more specifically.

however...wouldn't it be easier to make each pokemon an actor, so you could set their level + skills? then if they level up they will learn the skills, etc? That way you don't have to read out of a file to learn the moves... just a suggestion

 

I'm sorry, I wasn't specific enough.

 

The code for experience already works the way it should.

 

The script we need is one that checks the player's whole party to see which pokemon have gained experience. Then everytime it finds one, check to see if it is at a level where it would normally learn a move. Then, ask the trainer if they want to teach the pokemon that move.

 

Right now, it only performs that check for the last pokemon to fight.

 

Here's my attempt at writing the code we need in plain language. Perhaps after reading that you can figure out what we need to change with the original language to make it work like this:

 

[b]After battle ends
look at all pokemon in the party

do not look at pokemon that gained <= 0 exp

if pokemon has gained >0 exp

check to see if they are at a level where they would normally learn a new move[/b]

if pokemon has < 4 moves, automatically teach the pokemon that move

if pokemon has >= 4 moves, display message saying

"[pokemon] is trying to learn [move], but [pokemon] can only know 4 moves at a time"

"delete an old move to make room for the new move?"

if player says "yes", display message saying

"1..2..3..poof!"

"[pokemon] forgot [old move]"

"[pokemon] learned [new move]"

if player says "no", display message asking

"abandon learning [move]?"

if player says "yes", display message saying

"[pokemon] did not learn [move]"

if player says "no", display this message again

"[pokemon] is trying to learn [move], but [pokemon] can only know 4 moves at a time"

"delete an old move to make room for the new move?"

end

 

The code for learning new moves is already very similar to what I just posted, it's just that it only looks for the pokemon that was last used, not at the entire party.

 

I don't know anything about "actors" in RGSS, can you explain that?

Edited by Razor

Share this post


Link to post
Share on other sites
  • 0

Oh okay I see what you are saying now, But what I think you should do is work in the move learning with the experience...for example if your code already works (gives all the pokemon exp) then you simply store the pokemon's current level in a local variable, add exp, if their new level is greater than the temporary variable, check if they learn any moves at that level, ask the player, then move to the next pokemon. If the experience works (and gives each pokemon experience) then naturally after the block of code where you actually give the pokemon experience, is where you should be checking if they learned a new move (because like you said, you need to know which pokemon gained experience right? well if experience is added, at the same time you can check for a new move since at this point they must've gained exp.)

 

And actors are just the name for like characters, if you open the database, the first tab with all the characters are your actors...or are you already doing this? Because if you use the actors (accessible by $game_actors[index] or $game_party.actors[index] for the characters currently in the party) you can easily grab level data, strength, hp, exp etc. Although, it seems like you are modifying the way characters and levels works ALOT so I am not sure if this will necessarily help, you may have to change some things.

Share this post


Link to post
Share on other sites
  • 0

Oh okay I see what you are saying now, But what I think you should do is work in the move learning with the experience...for example if your code already works (gives all the pokemon exp) then you simply store the pokemon's current level in a local variable, add exp, if their new level is greater than the temporary variable, check if they learn any moves at that level, ask the player, then move to the next pokemon. If the experience works (and gives each pokemon experience) then naturally after the block of code where you actually give the pokemon experience, is where you should be checking if they learned a new move (because like you said, you need to know which pokemon gained experience right? well if experience is added, at the same time you can check for a new move since at this point they must've gained exp.)

 

And actors are just the name for like characters, if you open the database, the first tab with all the characters are your actors...or are you already doing this? Because if you use the actors (accessible by $game_actors[index] or $game_party.actors[index] for the characters currently in the party) you can easily grab level data, strength, hp, exp etc. Although, it seems like you are modifying the way characters and levels works ALOT so I am not sure if this will necessarily help, you may have to change some things.

 

I think this is the actual culprit:

 

     	pbDisplayPaused(_INTL("{1} grew to Level {2}!",thispoke.name,curlevel))
    	@scene.pbLevelUp(thispoke,battler,oldtotalhp,oldattack,
        	olddefense,oldspeed,oldspatk,oldspdef)
    	# Finding all moves learned at this level
    	atkdata=pbRgssOpen("Data/attacksRS.dat","rb")
    	offset=atkdata.getOffset(thisPokeSpecies-1)
    	length=atkdata.getLength(thisPokeSpecies-1)>>1
    	atkdata.pos=offset
    	for k in 0..length-1
     	atklevel=atkdata.fgetw
     	move=atkdata.fgetw
     	if atklevel==thispoke.level
      	# Learned a new move
      	pbLearnMove(j,move)
     	end
    	end
    	atkdata.close
   	end

 

I believe the code for pbLearnMove is just for how the game behaves regarding the learning of new moves.

 

This piece of code here (within pbGainEXP) appears to be the part of the code that actually triggers the move learning.

 

I think I'm sorta kinda understanding this a little now.

Share this post


Link to post
Share on other sites
  • 0

Yes that definitely is the portion that handles move learning, and pbLearnMove is actually learning the move...

 

I have a question though, did you write this code? If not could you contact the person who wrote it?

I wish i could help more, but because I can only see this small portion I am not really sure what each variable ACTUALLY holds...

And a few snippets I am not sure about:

for j in @battlers[i].participants
 @participants[j]=true # Add participant to global list
end

@participants is only referred to here...so i don't see the point of this (maybe there is another portion of the script that does something?)

and

for j in 0..@party1.length-1
thispoke=@party1[j]
next if !@party1[j] || !pbIsOwner?(0,j)
ispartic=0
level=@battlers[i].level
haveexpshare=(isConst?(thispoke.item,PBItems,:EXPSHARE)) ? 1 : 0
 for k in @battlers[i].participants
   ispartic=1 if k==j
 end

Just a snippet, but basically what I see happening, is "for j in 0..@party1.length-1" cycles j through 0, 1, 2, ... etc, until @party.length, then "for k in @battlers.participants" will cycle through each object held in @battlers.participants, if @battlers.participants does not hold numeric values, then "ispartic=1 if k==j" will never do anything... cause an object (that is non-numeric) != a numeric object... but I could be wrong about what @battlers.participants holds...

 

I really wish I could help you more than I have...but I can only make guesses and say what I think should be done, however unless I had the scripts I can only do so much...you could send me the scripts if you'd like (I can't make you) and I can take a look at all of them, maybe figure it out. But you are right the part of code you put there, is where the moves are learned, so what you need to find is the loop that goes through each pokemon, because I am assuming that's where the issue is.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...