# This class stores data on each Pokemon. Refer to $Trainer.party for an array# of each Pokemon in the Trainer's current party.class PokeBattle_Pokemonattr_reader(:totalhp) # Current Total HPattr_reader(:attack) # Current Attack statattr_reader(:defense) # Current Defense statattr_reader(:speed) # Current Speed statattr_reader(:spatk) # Current Special Attack statattr_reader(:spdef) # Current Special Defense statattr_accessor(:iv) # Array of 6 Individual Values for HP, Atk, Def,# Speed, Sp Atk, and Sp Defattr_accessor(:ev) # Effort Valuesattr_accessor(:species) # Species (National Pokedex number)attr_accessor(:personalID) # Personal IDattr_accessor(:trainerID) # 32-bit Trainer ID (the secret ID is in the upper# 16 bits)attr_accessor(:hp) # Current HPattr_accessor(:pokerus) # Pokérus strain and infection timeattr_accessor(:item) # Held itemattr_accessor(:itemRecycle) # Consumed held item (used in battle only)attr_accessor(:itemInitial) # Resulting held item (used in battle only)attr_accessor(:mail) # Mailattr_accessor(:fused) # The Pokémon fused into this oneattr_accessor(:name) # Nicknameattr_accessor(:exp) # Current experience pointsattr_accessor(:happiness) # Current happinessattr_accessor(:status) # Status problem (PBStatuses)attr_accessor(:statusCount) # Sleep count/Toxic flagattr_accessor(:eggsteps) # Steps to hatch egg, 0 if Pokémon is not an eggattr_accessor(:moves) # Moves (PBMove)attr_accessor(:firstmoves) # The moves known when this Pokémon was obtainedattr_accessor(:ballused) # Ball usedattr_accessor(:markings) # Markingsattr_accessor(:obtainMode) # Manner obtained:# 0 - met, 1 - as egg, 2 - traded,# 4 - fateful encounterattr_accessor(:obtainMap) # Map where obtainedattr_accessor(:obtainText) # Replaces the obtain map's name if not nilattr_accessor(:obtainLevel) # Level obtainedattr_accessor(:hatchedMap) # Map where an egg was hatchedattr_accessor(:language) # Languageattr_accessor(:ot) # Original Trainer's nameattr_accessor(:otgender) # Original Trainer's gender:# 0 - male, 1 - female, 2 - mixed, 3 - unknown# For information only, not used to verify# ownership of the Pokemonattr_accessor(:abilityflag) # Forces the first/second/hidden (0/1/2) abilityattr_accessor(:genderflag) # Forces male (0) or female (1)attr_accessor(:natureflag) # Forces a particular natureattr_accessor(:shinyflag) # Forces the shininess (true/false)attr_accessor(:ribbons) # Array of ribbonsattr_accessor :cool,:beauty,:cute,:smart,:tough,:sheen # Contest stats################################################################################# Ownership, obtained information################################################################################# Returns the gender of this Pokémon's original trainer (2=unknown).def otgender@otgender=2 if [email protected] return @otgenderend# Returns whether the specified Trainer is NOT this Pokemon's original trainer.def isForeign?(trainer)return @trainerID!=trainer.id || @ot!=trainer.nameend# Returns the public portion of the original trainer's ID.def publicIDreturn @trainerID&0xFFFFend# Returns this Pokémon's level when this Pokémon was obtained.def obtainLevel@obtainLevel=0 if [email protected] return @obtainLevelend# Returns the time when this Pokémon was obtained.def timeReceivedreturn @timeReceived ? Time.at(@timeReceived) : Time.gm(2000)end# Sets the time when this Pokémon was obtained.def timeReceived=(value)# Seconds since Unix epochif value.is_a?(Time)@timeReceived=value.to_ielse@timeReceived=valueendend# Returns the time when this Pokémon hatched.def timeEggHatchedif obtainMode==1return @timeEggHatched ? Time.at(@timeEggHatched) : Time.gm(2000)elsereturn Time.gm(2000)endend# Sets the time when this Pokémon hatched.def timeEggHatched=(value)# Seconds since Unix epochif value.is_a?(Time)@timeEggHatched=value.to_ielse@timeEggHatched=valueendenddef birthsignif obtainMode==1return pbGetZodiacName(self.timeEggHatched.mon)endend################################################################################# Form Change Time################################################################################def form_change_timeif [email protected] _change_time@form_change_time=Time.nowendreturn @form_change_timeend################################################################################# Party Index# Returns the index of the pokemon in the trainers party, if applicable################################################################################def partyIndexret=-1return ret if !$Trainer || !($Trainer.party)for i in 0...$Trainer.party.lengthreturn i if $Trainer.party[i]==selfendreturn retend################################################################################# Level################################################################################# Returns this Pokemon's level.def levelreturn PBExperience.pbGetLevelFromExperience(@exp,self.growthrate)end# Sets this Pokemon's level by changing its Exp. Points.def level=(value)if value<1 || value>PBExperience::MAXLEVELraise ArgumentError.new(_INTL("The level number ({1}) is invalid.",value))endself.exp=PBExperience.pbGetStartExperience(value,self.growthrate)end# Returns whether this Pokemon is an egg.def isEgg?return @eggsteps>0enddef egg?; return isEgg?; end # DEPRECATED# Returns this Pokemon's growth rate.def growthratedexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,20)ret=dexdata.fgetbdexdata.closereturn retend# Returns this Pokemon's base Experience value.def baseExpdexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,38)ret=dexdata.fgetwdexdata.closereturn retend################################################################################# Gender################################################################################# Returns this Pokemon's gender. 0=male, 1=female, 2=genderlessdef genderreturn @genderflag if @genderflag!=nildexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,18)genderbyte=dexdata.fgetbdexdata.closecase genderbytewhen 255return 2 # genderlesswhen 254return 1 # always femaleelse [email protected] &0xFFreturn PokeBattle_Pokemon.isFemale(lowbyte,genderbyte) ? 1 : 0endend# Helper function that determines whether the input values would make a female.def self.isFemale(b,genderRate)return true if genderRate==254 # AlwaysFemalereturn false if genderRate==255 # Genderlessreturn b<=genderRateend# Returns whether this Pokémon is male.def isMale?return self.gender==0end# Returns whether this Pokémon is female.def isFemale?return self.gender==1end# Sets this Pokémon's gender to a particular gender (if possible).def setGender(value)dexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,18)genderbyte=dexdata.fgetbdexdata.closeif genderbyte!=255 && genderbyte!=0 && genderbyte!=254@genderflag=valueendenddef makeMale; setGender(0); enddef makeFemale; setGender(1); end################################################################################# Ability################################################################################# Returns the index of this Pokémon's ability.def abilityIndex [email protected] !=nil ? @abilityflag : (@personalID&1)return abilend# Returns the ID of this Pokemon's ability.def abilityabil=abilityIndexdexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,29)ret1=dexdata.fgetbret2=dexdata.fgetbpbDexDataOffset(dexdata,@species,40)h1=dexdata.fgetbh2=dexdata.fgetbh3=dexdata.fgetbh4=dexdata.fgetbdexdata.closeret=ret1if abil==2return h1 if h1>0abil=(@personalID&1)elsif abil==3return h2 if h2>0abil=(@personalID&1)elsif abil==4return h3 if h3>0abil=(@personalID&1)elsif abil==5return h4 if h4>0abil=(@personalID&1)endif abil==1ret=ret2ret=ret1 if ret2==0endreturn retend# Sets this Pokémon's ability to a particular ability (if possible).def setAbility(value)@abilityflag=valueend# Returns the list of abilities this Pokémon can have.def getAbilityListabils=[]; ret=[[],[]]dexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,29)abils.push(dexdata.fgetb)abils.push(dexdata.fgetb)pbDexDataOffset(dexdata,@species,40)abils.push(dexdata.fgetb)abils.push(dexdata.fgetb)abils.push(dexdata.fgetb)abils.push(dexdata.fgetb)dexdata.closefor i in 0...abils.lengthnext if !abils[i] || abils[i]<=0ret[0].push(abils[i]); ret[1].push(i)endreturn retend################################################################################# Nature################################################################################# Returns the ID of this Pokémon's nature.def naturereturn @natureflag if @natureflag!=nilreturn @personalID%25end# Sets this Pokémon's nature to a particular nature.def setNature(value)if value.is_a?(String) || value.is_a?(Symbol)value=getID(PBNatures,value)end@natureflag=valueself.calcStatsend################################################################################# Shininess################################################################################# Returns whether this Pokemon is shiny (differently colored).def isShiny?return @shinyflag if @shinyflag!=nil [email protected] ^@trainerIDb=a&0xFFFFc=(a>>16)&0xFFFFd=b^creturn (d =16strain=1+rand(15)endtime=1+(strain%4)@pokerus=time@pokerus|=strain<<4end# Resets the infection time for this Pokemon's Pokérus (even if cured).def resetPokerusTimereturn if @pokerus==0 [email protected] %16time=1+(strain%4)@pokerus=time@pokerus|=strain<<4end# Reduces the time remaining for this Pokemon's Pokérus (if infected).def lowerPokerusCountreturn if self.pokerusStage!=1@pokerus-=1end# Returns the Pokérus infection stage for this Pokemon.def pokerusStagereturn 0 if [email protected] || @pokerus==0 # Not infectedreturn 2 if @pokerus>0 && (@pokerus%16)==0 # Curedreturn 1 # Infectedend################################################################################# Types################################################################################# Returns whether this Pokémon has the specified type.def hasType?(type)if type.is_a?(String) || type.is_a?(Symbol)return isConst?(self.type1,PBTypes,type) || isConst?(self.type2,PBTypes,type)elsereturn self.type1==type || self.type2==typeendend# Returns this Pokémon's first type.def type1dexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,8)ret=dexdata.fgetbdexdata.closereturn retend# Returns this Pokémon's second type.def type2dexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,9)ret=dexdata.fgetbdexdata.closereturn retend################################################################################# Moves################################################################################# Returns the number of moves known by the Pokémon.def numMovesret=0for i in 0...4ret+=1 if @moves[i].id!=0endreturn retend# Returns true if the Pokémon knows the given move.def knowsMove?(move)if move.is_a?(String) || move.is_a?(Symbol)move=getID(PBMoves,move)endreturn false if !move || move<=0for i in 0...4return true if @moves[i].id==moveendreturn falseend# Returns the list of moves this Pokémon can learn by levelling up.def getMoveListmovelist=[]atkdata=pbRgssOpen("Data/attacksRS.dat","rb")offset=atkdata.getOffset(@species-1)length=atkdata.getLength(@species-1)>>1atkdata.pos=offsetfor k in 0..length-1level=atkdata.fgetwmove=atkdata.fgetwmovelist.push([level,move])endatkdata.closereturn movelistend# Sets this Pokémon's movelist to the default movelist it originally had.def resetMovesmoves=self.getMoveListmovelist=[]for i in movesif i[0]<=self.levelmovelist[movelist.length]=i[1]endendmovelist|=[] # Remove duplicateslistend=movelist.length-4listend=0 if listend<0j=0for i in listend...listend+4moveid=(i>=movelist.length) ? 0 : movelist[i]@moves[j]=PBMove.new(moveid)j+=1endend# Silently learns the given move. Will erase the first known move if it has to.def pbLearnMove(move)if move.is_a?(String) || move.is_a?(Symbol)move=getID(PBMoves,move)endreturn if move<=0for i in 0...4if @moves[i].id==movej=i+1; while j<4break if @moves[j].id==0 [email protected] [j]@moves[j] [email protected] [j-1]@moves[j-1]=tmpj+=1endreturnendendfor i in 0...4if @moves[i].id==0@moves[i]=PBMove.new(move)returnendend@moves[0] [email protected] [1]@moves[1] [email protected] [2]@moves[2] [email protected] [3]@moves[3]=PBMove.new(move)end# Deletes the given move from the Pokémon.def pbDeleteMove(move)if move.is_a?(String) || move.is_a?(Symbol)move=getID(PBMoves,move)endreturn if !move || move<=0newmoves=[]for i in 0...4newmoves.push(@moves[i]) if @moves[i].id!=moveendnewmoves.push(PBMove.new(0))for i in 0...4@moves[i]=newmoves[i]endend# Deletes the move at the given index from the Pokémon.def pbDeleteMoveAtIndex(index)newmoves=[]for i in 0...4newmoves.push(@moves[i]) if i!=indexendnewmoves.push(PBMove.new(0))for i in 0...4@moves[i]=newmoves[i]endend# Deletes all moves from the Pokémon.def pbDeleteAllMovesfor i in 0...4@moves[i]=PBMove.new(0)endend# Copies currently known moves into a separate array, for Move Relearner.def pbRecordFirstMoves@firstmoves=[]for i in 0...4@firstmoves.push(@moves[i].id) if @moves[i].id>0endend################################################################################# Contest attributes, ribbons################################################################################def cool; @cool ? @cool : 0; enddef beauty; @beauty ? @beauty : 0; enddef cute; @cute ? @cute : 0; enddef smart; @smart ? @smart : 0; enddef tough; @tough ? @tough : 0; enddef sheen; @sheen ? @sheen : 0; end# Returns the number of ribbons this Pokemon has.def ribbonCount@ribbons=[] if [email protected] return @ribbons.lengthend# Returns whether this Pokémon has the specified ribbon.def hasRibbon?(ribbon)@ribbons=[] if [email protected] ribbon=getID(PBRibbons,ribbon) if !ribbon.is_a?(Integer)return false if ribbon==0return @ribbons.include?(ribbon)end# Gives this Pokémon the specified ribbon.def giveRibbon(ribbon)@ribbons=[] if [email protected] ribbon=getID(PBRibbons,ribbon) if !ribbon.is_a?(Integer)return if ribbon==0@ribbons.push(ribbon) if [email protected] ?(ribbon)end# Replaces one ribbon with the next one along, if possible.def upgradeRibbon(*arg)@ribbons=[] if [email protected] for i in 0...arg.length-1for j in [email protected] thisribbon=(arg[i].is_a?(Integer)) ? arg[i] : getID(PBRibbons,arg[i])if @ribbons[j]==thisribbonnextribbon=(arg[i+1].is_a?(Integer)) ? arg[i+1] : getID(PBRibbons,arg[i+1])@ribbons[j]=nextribbonreturn nextribbonendendendif !hasRibbon?(arg[arg.length-1])firstribbon=(arg[0].is_a?(Integer)) ? arg[0] : getID(PBRibbons,arg[0])giveRibbon(firstribbon)return firstribbonendreturn 0end# Removes the specified ribbon from this Pokémon.def takeRibbon(ribbon)return if [email protected] ribbon=getID(PBRibbons,ribbon) if !ribbon.is_a?(Integer)return if ribbon==0for i in [email protected] if @ribbons[i]==ribbon@ribbons[i]=nil; breakendend@ribbons.compact!end# Removes all ribbons from this Pokémon.def clearAllRibbons@ribbons=[]end################################################################################# Other################################################################################# Returns whether this Pokémon has a hold item.def hasItem?(value=0)if value==0return self.item>0elseif value.is_a?(String) || value.is_a?(Symbol)value=getID(PBItems,value)endreturn self.item==valueendreturn falseend# Sets this Pokémon's item. Accepts symbols.def setItem(value)if value.is_a?(String) || value.is_a?(Symbol)value=getID(PBItems,value)endself.item=valueend# Returns the items this species can be found holding in the wild.def wildHoldItemsdexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,48)itemcommon=dexdata.fgetwitemuncommon=dexdata.fgetwitemrare=dexdata.fgetwdexdata.closeitemcommon=0 if !itemcommonitemuncommon=0 if !itemuncommonitemrare=0 if !itemrarereturn [itemcommon,itemuncommon,itemrare]end# Returns this Pokémon's mail.def mailreturn nil if [email protected] if @mail.item==0 || !self.hasItem? || @mail.item!=self.item@mail=nilreturn nilendreturn @mailend# Returns this Pokémon's language.def language; @language ? @language : 0; end# Returns the markings this Pokémon has.def markings@markings=0 if [email protected] return @markingsend# Returns a string stating the Unown form of this Pokémon.def unownShapereturn "ABCDEFGHIJKLMNOPQRSTUVWXYZ?!"[@form,1]end# Returns the weight of this Pokémon.def weightdexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,35)weight=dexdata.fgetwdexdata.closereturn weightend# Returns the EV yield of this Pokémon.def evYieldret=[]dexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,23)for i in 0...6v=dexdata.fgetbv=0 if !vret.push(v)enddexdata.closereturn retend# Sets this Pokémon's HP.def hp=(value)value=0 if value<0@hp=valueif @hp==0@status=0@statusCount=0endend# Heals all HP of this Pokémon.def healHPreturn if egg?end# Heals the status problem of this Pokémon.def healStatusreturn if egg?@status=0@statusCount=0end# Heals all PP of this Pokémon.def healPP(index=-1)return if egg?if index>=0@moves[index] [email protected] [index].totalppelsefor i in 0...4@moves[i] [email protected] [i].totalppendendend# Heals all HP, PP, and status problems of this Pokémon.def healreturn if egg?healHPhealStatushealPPend# Changes the happiness of this Pokémon depending on what happened to change it.def changeHappiness(method)gain=0; luxury=falsecase methodwhen "walking"gain=1gain+=1 if @happiness<200gain+=1 if @obtainMap==$game_map.map_idluxury=truewhen "level up"gain=2gain=3 if @happiness<200gain=5 if @happiness<100luxury=truewhen "groom"gain=4gain=10 if @happiness<200luxury=truewhen "faint"gain=-1when "vitamin"gain=2gain=3 if @happiness<200gain=5 if @happiness<100when "EV berry"gain=2gain=5 if @happiness<200gain=10 if @happiness<100when "powder"gain=-10gain=-5 if @happiness<200when "Energy Root"gain=-15gain=-10 if @happiness<200when "Revival Herb"gain=-20gain=-15 if @happiness<200elseKernel.pbMessage(_INTL("Unknown happiness-changing method."))endgain+=1 if luxury && self.ballused==pbGetBallType(:LUXURYBALL)if isConst?(self.item,PBItems,OOTHEBELL) && gain>0gain=(gain*3.0/2).roundend@happiness+=gain@happiness=[[255,@happiness].min,0].maxend################################################################################# Stat calculations, Pokémon creation################################################################################# Returns this Pokémon's base stats. An array of six values.def baseStatsdexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,10)ret=[dexdata.fgetb, # HPdexdata.fgetb, # Attackdexdata.fgetb, # Defensedexdata.fgetb, # Speeddexdata.fgetb, # Special Attackdexdata.fgetb # Special Defensedexdata.closereturn retend# Returns the maximum HP of this Pokémon.def calcHP(base,level,iv,ev)return 1 if base==1return ((base*2+iv+(ev>>2))*level/100).floor+level+10end# Returns the specified stat of this Pokémon (not used for total HP).def calcStat(base,level,iv,ev,pv)return ((((base*2+iv+(ev>>2))*level/100).floor+5)*pv/100).floorend# Recalculates this Pokémon's stats.def calcStatsnature=self.naturestats=[]pvalues=[100,100,100,100,100]nd5=(nature/5).floornm5=(nature%5).floorif nd5!=nm5pvalues[nd5]=110pvalues[nm5]=90endlevel=self.levelbs=self.baseStatsfor i in 0..5base=bs[i]if i==PBStats::HPstats[i]=calcHP(base,level,@iv[i],@ev[i])elsestats[i]=calcStat(base,level,@iv[i],@ev[i],pvalues[i-1])endend [email protected] @hp@totalhp=stats[0]if @hp>0@hp=1 if @hp<=0 [email protected] if @hp>@totalhpend@attack=stats[1]@defense=stats[2]@speed=stats[3]@spatk=stats[4]@spdef=stats[5]end# Creates a new Pokémon object.# species - Pokémon species.# level - Pokémon level.# player - PokeBattle_Trainer object for the original trainer.# withMoves - If false, this Pokémon has no moves.def initialize(species,level,player=nil,withMoves=true)if species.is_a?(String) || species.is_a?(Symbol)species=getID(PBSpecies,species)endcname=getConstantName(PBSpecies,species) rescue nilif !species || species<1 || species>PBSpecies.maxValue || !cnameraise ArgumentError.new(_INTL("The species number (no. {1} of {2}) is invalid.",species,PBSpecies.maxValue))return nilendtime=pbGetTimeNow@timeReceived=time.getgm.to_i # Use GMT@form_change_time=pbGetTimeNow@species=species# Individual Values@personalID=rand(256)@personalID|=rand(256)<<8@personalID|=rand(256)<<16@personalID|=rand(256)<<24@hp=1@totalhp=1@ev=[0,0,0,0,0,0]@iv=[]@iv[0]=rand(32)@iv[1]=rand(32)@iv[2]=rand(32)@iv[3]=rand(32)@iv[4]=rand(32)@iv[5]=rand(32)if player@trainerID=player.id@ot=player.name@otgender=player.gender@language=player.languageelse@trainerID=0@ot=""@otgender=2enddexdata=pbOpenDexDatapbDexDataOffset(dexdata,@species,19)@happiness=dexdata.fgetbdexdata.close@name=PBSpecies.getName(@species)@eggsteps=0@status=0@statusCount=0@item=0@mail=nil@fused=nil@ribbons=[]@moves=[]self.ballused=0self.level=levelcalcStatsif $game_map@obtainMap=$game_map.map_id@obtainText=nil@obtainLevel=levelelse@obtainMap=0@obtainText=nil@obtainLevel=levelend@obtainMode=0 # Met@obtainMode=4 if $game_switches && $game_switches[FATEFUL_ENCOUNTER_SWITCH]@hatchedMap=0if withMovesatkdata=pbRgssOpen("Data/attacksRS.dat","rb")offset=atkdata.getOffset(species-1)length=atkdata.getLength(species-1)>>1atkdata.pos=offset# Generating move listmovelist=[]for i in 0..length-1alevel=atkdata.fgetwmove=atkdata.fgetwif alevel<=levelmovelist[movelist.length]=moveendendatkdata.closemovelist|=[] # Remove duplicates# Use the last 4 items in the move listlistend=movelist.length-4listend=0 if listend<0j=0for i in listend...listend+4moveid=(i>=movelist.length) ? 0 : movelist[i]@moves[j]=PBMove.new(moveid)j+=1endendendend