Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ################################################################################
- # Choose a move to use.
- ################################################################################
- def pbChooseMoves(index)
- attacker=@battlers[index]
- scores=[0,0,0,0]
- targets=nil
- myChoices=[]
- totalscore=0
- target=-1
- skill=0
- wildbattle=!@opponent && pbIsOpposing?(index)
- #if wildbattle (commented out by JZ)
- if false==true # Nightmare Conquer score selection by JZ, which i made useless, #by low
- skill=100
- baseDamageArray=[]
- opponent=attacker.pbPartner
- for j in 0...attacker.moves.length
- next if attacker.moves[j].id < 1
- # check attacker.moves[j].basedamage and if this is 0 instead check the status method
- dmgValue = pbRoughDamage(attacker.moves[j],attacker,opponent,skill,attacker.moves[j].basedamage)
- if attacker.moves[j].basedamage!=0
- if opponent.hp==0
- dmgPercent = 0
- else
- dmgPercent = (dmgValue*100)/(opponent.hp)
- dmgPercent = 110 if dmgPercent > 110
- end
- else
- dmgPercent = pbStatusDamage(attacker.moves[j])
- end
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Conquered vs Partner: Move " + PBMoves.getName(attacker.moves[j].id).to_s + " has rough damage " + dmgValue.to_s + " and damage % " +dmgPercent.to_s
- #~ end
- baseDamageArray.push(dmgPercent)
- end
- for i in 0...attacker.moves.length
- if pbCanChooseMove?(index,i,false)
- scores[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill,baseDamageArray[i])
- # added by JZ to make them not target partner
- if attacker.moves[i].target==PBTargets::Partner
- scores[i]=-1
- end
- myChoices.push(i)
- else
- scores[i] = -1
- end
- end
- # JZ note: ok so if the conquered mon ends up having 0 effective moves against its partner,
- # example: Arcanine with Surf + Water Gun next to partner Water Absorb mon
- # it'll just use a random move and this is so improbable I'm too lazy to account for it
- # commented out by JZ
- #for i in 0...4
- # if pbCanChooseMove?(index,i,false)
- # #scores[i]=100 # by SH MARK
- # myChoices.push(i)
- # totalscore+=100
- # end
- #end
- else
- skill=100 if wildbattle # added by JZ to make bosses harder
- skill=(pbGetOwner(attacker.index).skill || 0) rescue 100
- opponent=attacker.pbOppositeOpposing
- if @doublebattle && ((!opponent.isFainted? && !opponent.pbPartner.isFainted?) || !attacker.pbPartner.isFainted?)
- # Choose a target and move. Also care about partner.
- otheropp=opponent.pbPartner
- notopp=attacker.pbPartner ###
- scoresAndTargets=[]
- targets=[-1,-1,-1,-1]
- maxscore1=0
- maxscore2=0
- totalscore1=0
- totalscore2=0
- baseDamageArray=[]
- baseDamageArray2=[]
- baseDamageArray3=[] ###
- for j in 0...attacker.moves.length
- next if attacker.moves[j].id < 1
- # check attacker.moves[j].basedamage and if this is 0 instead check the status method
- dmgValue = pbRoughDamage(attacker.moves[j],attacker,opponent,skill,attacker.moves[j].basedamage)
- if attacker.moves[j].basedamage!=0
- if opponent.hp==0
- dmgPercent = 0
- else
- dmgPercent = (dmgValue*100)/(opponent.hp)
- dmgPercent = 110 if dmgPercent > 110
- end
- else
- dmgPercent = pbStatusDamage(attacker.moves[j])
- end
- baseDamageArray.push(dmgPercent)
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Vs Opp 1: Move " + PBMoves.getName(attacker.moves[j].id).to_s + " has rough damage " + dmgValue.to_s + " and damage % " +dmgPercent.to_s
- #~ end
- #Second opponent
- dmgValue2 = pbRoughDamage(attacker.moves[j],attacker,otheropp,skill,attacker.moves[j].basedamage)
- if attacker.moves[j].basedamage!=0
- if otheropp.hp==0
- dmgPercent2=0
- else
- dmgPercent2 = (dmgValue2*100)/(otheropp.hp)
- dmgPercent2 = 110 if dmgPercent2 > 110
- end
- else
- dmgPercent2 = pbStatusDamage(attacker.moves[j])
- end
- baseDamageArray2.push(dmgPercent2)
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Vs Opp 2: Move " + PBMoves.getName(attacker.moves[j].id).to_s + " has rough damage " + dmgValue2.to_s + " and damage % " +dmgPercent2.to_s
- #~ end
- #Partner ###
- dmgValue3 = pbRoughDamage(attacker.moves[j],attacker,notopp,skill,attacker.moves[j].basedamage)
- if attacker.moves[j].basedamage!=0
- if notopp.hp==0
- dmgPercent3=0
- else
- dmgPercent3 = (dmgValue3*100)/(notopp.hp)
- dmgPercent3 = 110 if dmgPercent3 > 110
- end
- else
- dmgPercent3 = pbStatusDamage(attacker.moves[j])
- end
- baseDamageArray3.push(dmgPercent3)
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Vs Partner: Move " + PBMoves.getName(attacker.moves[j].id).to_s + " has rough damage " + dmgValue3.to_s + " and damage % " +dmgPercent3.to_s
- #~ end
- end
- for i in 0...attacker.moves.length
- if pbCanChooseMove?(index,i,false)
- score1=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill,baseDamageArray[i],baseDamageArray,i)
- score2=pbGetMoveScore(attacker.moves[i],attacker,otheropp,skill,baseDamageArray2[i],baseDamageArray2,i)
- totalscore = score1+score2
- if (attacker.moves[i].target&0x08)!=0 # Targets all users
- score1=totalscore # Consider both scores as it will hit BOTH targets
- score2=totalscore
- if attacker.pbPartner.isFainted? || attacker.pbPartner.hasWorkingAbility(:TELEPATHY) # No partner
- score1*=1.66
- score2*=1.66
- else
- # If this move can also target the partner, get the partner's
- # score too
- v=pbRoughDamage(attacker.moves[j],attacker,attacker.pbPartner,skill,attacker.moves[j].basedamage)
- # TENTATIVE fix 0 division error by JZ
- #p=(v*100)/(attacker.pbPartner.hp)
- if attacker.pbPartner.hp==0
- p=1
- else
- p=(v*100)/(attacker.pbPartner.hp)
- end
- # end block
- s=pbGetMoveScore(attacker.moves[i],attacker,attacker.pbPartner,skill,p)
- if (isConst?(attacker.moves[i],PBTypes,:FIRE) &&
- attacker.pbPartner.hasWorkingAbility(:FLASHFIRE)) ||
- # Wind Force #by low
- (isConst?(attacker.moves[i],PBTypes,:FLYING) &&
- attacker.pbPartner.hasWorkingAbility(:WINDFORCE)) ||
- (isConst?(attacker.moves[i],PBTypes,:FAIRY) &&
- attacker.pbPartner.hasWorkingAbility(:DISENCHANT)) ||
- (isConst?(attacker.moves[i],PBTypes,:WATER) &&
- (attacker.pbPartner.hasWorkingAbility(:WATERABSORB) ||
- attacker.pbPartner.hasWorkingAbility(:STORMDRAIN) ||
- attacker.pbPartner.hasWorkingAbility(:DRYSKIN))) ||
- (isConst?(attacker.moves[i],PBTypes,:GRASS) &&
- attacker.pbPartner.hasWorkingAbility(:SAPSIPPER)) ||
- (isConst?(attacker.moves[i],PBTypes,:ELECTRIC) &&
- (attacker.pbPartner.hasWorkingAbility(:VOLTABSORB) ||
- attacker.pbPartner.hasWorkingAbility(:LIGHTNINGROD) ||
- attacker.pbPartner.hasWorkingAbility(:MOTORDRIVE)))
- score1*=2.00
- score2*=2.00
- else
- if (attacker.pbPartner.hp.to_f)/attacker.pbPartner.totalhp>0.10 || ((attacker.pbPartner.pbSpeed<attacker.pbSpeed) ^ (@field.effects[PBEffects::TrickRoom]!=0))
- s = 100-s
- s=0 if s<0
- s/=100.0
- s *= 0.5 # multiplier to control how much to arbitrarily care about hitting partner; lower cares more
- if (attacker.pbPartner.pbSpeed<attacker.pbSpeed) ^ (@field.effects[PBEffects::TrickRoom]!=0)
- s *= 0.5 # care more if we're faster and would knock it out before it attacks
- end
- score1*=s
- score2*=s
- end
- end
- end
- score1=score1.to_i
- score2=score2.to_i
- PBDebug.log(sprintf("%s: Final Score after Multi-Target Adjustment: %d",PBMoves.getName(attacker.moves[i].id),score1))
- PBDebug.log(sprintf(""))
- end
- if attacker.moves[i].target==PBTargets::AllOpposing # Consider both scores as it will hit BOTH targets
- totalscore = score1+score2
- score1=totalscore
- score2=totalscore
- PBDebug.log(sprintf("%s: Final Score after Multi-Target Adjustment: %d",PBMoves.getName(attacker.moves[i].id),score1))
- PBDebug.log(sprintf(""))
- end
- myChoices.push(i)
- scoresAndTargets.push([i*2,i,score1,opponent.index])
- scoresAndTargets.push([i*2+1,i,score2,otheropp.index])
- else
- scoresAndTargets.push([i*2,i,-1,opponent.index])
- scoresAndTargets.push([i*2+1,i,-1,otheropp.index])
- end
- end
- for i in 0...attacker.moves.length ### This whole bit
- if pbCanChooseMove?(index,i,false)
- if attacker.moves[i].function == 0xDF || attacker.moves[i].function == 0x63 || attacker.moves[i].function == 0x67 ||
- attacker.moves[i].function == 0xA0 || attacker.moves[i].function == 0xC1 || attacker.moves[i].function == 0x141 ||
- attacker.moves[i].function == 0x40 || attacker.moves[i].function == 0x41 || attacker.moves[i].function == 0x66
- # Heal Pulse, Simple Beam, Skill Swap, Frost Breath, Beat Up, Topsy-Turvy, Psych Up, Swagger, Flatter, Entrainment
- partnerscore=pbGetMoveScore(attacker.moves[i],attacker,notopp,skill,baseDamageArray3[i],baseDamageArray3,i)
- PBDebug.log(sprintf("%s: Score for using on partner: %d",PBMoves.getName(attacker.moves[i].id),partnerscore))
- PBDebug.log(sprintf(""))
- scoresAndTargets.push([i*10,i,partnerscore,notopp.index])
- end
- end
- end
- scoresAndTargets.sort!{|a,b|
- if a[2]==b[2] # if scores are equal
- a[0]<=>b[0] # sort by index (for stable comparison)
- else
- b[2]<=>a[2]
- end
- }
- for i in 0...scoresAndTargets.length
- idx=scoresAndTargets[i][1]
- thisScore=scoresAndTargets[i][2]
- if thisScore>0 || thisScore==-1
- if scores[idx]==0 || ((scores[idx]==thisScore && pbAIRandom(10)<5) ||
- (scores[idx] < thisScore))
- # (scores[idx]!=thisScore && pbAIRandom(10)<3))
- scores[idx]=thisScore
- targets[idx]=scoresAndTargets[i][3]
- end
- end
- end
- else
- # Choose a move. There is only 1 opposing Pokémon.
- if @doublebattle && opponent.isFainted?
- opponent=opponent.pbPartner
- end
- baseDamageArray=[]
- baseDamageArrayAdj=[]
- for j in 0...attacker.moves.length
- next if attacker.moves[j].id < 1
- # check attacker.moves[j].basedamage and if this is 0 instead check the status method
- dmgValue = pbRoughDamage(attacker.moves[j],attacker,opponent,skill,attacker.moves[j].basedamage)
- if attacker.moves[j].basedamage!=0
- # TENTATIVE fix 0 division error by JZ?
- #dmgPercent = (dmgValue*100)/(opponent.hp)
- if opponent.hp==0
- dmgPercent=1
- else
- dmgPercent = (dmgValue*100)/(opponent.hp)
- end
- # end block
- dmgPercent = 110 if dmgPercent > 110
- if attacker.moves[j].function == 0x115 || attacker.moves[j].function == 0xC3 ||
- attacker.moves[j].function == 0xC4 || attacker.moves[j].function == 0xC5 ||
- attacker.moves[j].function == 0xC6 || attacker.moves[j].function == 0xC7 ||
- attacker.moves[j].function == 0xC8
- dmgPercentAdj = (dmgPercent * 0.5)
- else
- dmgPercentAdj = dmgPercent
- end
- else
- dmgPercent = pbStatusDamage(attacker.moves[j])
- dmgPercentAdj = dmgPercent
- end
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Vs Only Opponent: Move " + PBMoves.getName(attacker.moves[j].id).to_s + " has rough damage " + dmgValue.to_s + " and damage % " +dmgPercent.to_s
- #~ end
- baseDamageArray.push(dmgPercent)
- baseDamageArrayAdj.push(dmgPercentAdj)
- end
- for i in 0...attacker.moves.length
- if pbCanChooseMove?(index,i,false)
- scores[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill,baseDamageArray[i],baseDamageArrayAdj,i)
- myChoices.push(i)
- else
- scores[i] = -1
- end
- end
- end
- end
- maxscore=0
- for i in 0...attacker.moves.length
- scores[i]=0 if scores[i]<0
- maxscore=scores[i] if scores[i]>maxscore
- totalscore+=scores[i]
- end
- #~ for i in 0...attacker.moves.length
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "Move " + PBMoves.getName(attacker.moves[i].id).to_s + " has final score " + scores[i].to_s
- #~ end
- #~ end
- #~ File.open("AI_final_log.txt", "a") do |line|
- #~ line.puts "============================================"
- #~ end
- # added for master debug by JZ
- # this takes all the moves and finds their scores, seeing if any of them break
- # does not however check for validity of scores
- # also only tests said moves a given user/opponent pair of abilities and items
- # a comprehensive test would be infeasible in terms of time so only one test was run on one given combo
- #for i in 1..300
- #for i in 301..621
- #~ for i in 1..687
- #~ for i in 900..PBMoves.maxValue
- #~ mirrored = PBMove.new(i)
- #~ mirrmove = PokeBattle_Move.pbFromPBMove(self,mirrored)
- #~ next if mirrored==nil
- #~ dmgValue = pbRoughDamage(mirrmove,attacker,opponent,skill,mirrmove.basedamage)
- #~ if mirrmove.basedamage!=0
- #~ dmgPercent = (dmgValue*100)/(opponent.hp)
- #~ dmgPercent = 110 if dmgPercent > 110
- #~ else
- #~ dmgPercent=pbStatusDamage(mirrmove)
- #~ end
- #~ File.open("AI_master_log.txt", "a") do |line|
- #~ line.puts "Move " + i.to_s + " aka " + PBMoves.getName(mirrored.id).to_s + " has rough damage " + dmgValue.to_s + " and damage % " + dmgPercent.to_s
- #~ end
- #~ score=pbGetMoveScore(mirrmove,attacker,opponent,skill,dmgPercent)
- #~ File.open("AI_master_log.txt", "a") do |line|
- #~ line.puts "Move " + i.to_s + " aka " + PBMoves.getName(mirrored.id).to_s + " has final score " + score.to_s
- #~ end
- #~ end
- # end master debug
- # Minmax choices depending on AI
- #if !wildbattle && skill>=PBTrainerAI.mediumSkill (commented out by JZ)
- if true
- threshold=(skill>=PBTrainerAI.bestSkill) ? 1.5 : (skill>=PBTrainerAI.highSkill) ? 2 : 3
- newscore=(skill>=PBTrainerAI.bestSkill) ? 5 : (skill>=PBTrainerAI.highSkill) ? 10 : 15
- for i in 0...scores.length
- if scores[i]>newscore && scores[i]*threshold<maxscore
- totalscore-=(scores[i]-newscore)
- scores[i]=newscore
- end
- end
- maxscore=0
- for i in 0...attacker.moves.length
- maxscore=scores[i] if scores[i] && scores[i]>maxscore
- end
- end
- if true #!wildbattle && maxscore>100 (commented out by JZ)
- stdev=pbStdDev(scores)
- preferredMoves=[]
- for i in 0...attacker.moves.length
- if attacker.moves[i].id!=0 && (scores[i]>=(maxscore*0.8)) && pbCanChooseMove?(index,i,false)
- preferredMoves.push(i)
- preferredMoves.push(i) if scores[i]==maxscore # Doubly prefer the best move
- end
- end
- if preferredMoves.length>0
- i=preferredMoves[pbAIRandom(preferredMoves.length)]
- PBDebug.log("[AI] Prefer #{PBMoves.getName(attacker.moves[i].id)}")
- pbRegisterMove(index,i,false)
- target=targets[i] if targets
- if @doublebattle && target>=0
- pbRegisterTarget(index,target)
- end
- return
- end
- end
- #if !wildbattle && attacker.turncount (commented out by JZ)
- if attacker.turncount
- badmoves=false
- if ((maxscore<=20 && attacker.turncount>2) ||
- (maxscore<=30 && attacker.turncount>5)) && pbAIRandom(10)<8
- badmoves=true
- end
- if totalscore<100 && attacker.turncount>1
- badmoves=true
- movecount=0
- for i in 0...attacker.moves.length
- if attacker.moves[i].id!=0
- if scores[i]>0 && attacker.moves[i].basedamage>0
- badmoves=false
- end
- movecount+=1
- end
- end
- badmoves=badmoves && pbAIRandom(10)!=0
- end
- if badmoves
- # Attacker has terrible moves, try switching instead
- if pbEnemyShouldWithdrawEx?(index,true)
- if $INTERNAL
- PBDebug.log("[AI] Switching due to terrible moves")
- PBDebug.log([index,@choices[index][0],@choices[index][1],
- pbCanChooseNonActive?(index),
- @battlers[index].pbNonActivePokemonCount()].inspect)
- end
- return
- end
- end
- end
- if maxscore<=0
- # If all scores are 0 or less, choose a move at random
- if myChoices.length>0
- pbRegisterMove(index,myChoices[pbAIRandom(myChoices.length)],false)
- else
- pbAutoChooseMove(index)
- end
- else
- randnum=pbAIRandom(totalscore)
- cumtotal=0
- for i in 0...attacker.moves.length
- if scores[i]>0
- cumtotal+=scores[i]
- if randnum<cumtotal
- pbRegisterMove(index,i,false)
- target=targets[i] if targets
- break
- end
- end
- end
- end
- PBDebug.log("[AI] Will use #{@choices[index][2].name}") if @choices[index][2]
- if @doublebattle && target>=0
- pbRegisterTarget(index,target)
- end
- end
- ################################################################################
- # Decide whether the opponent should Mega Evolve their Pokémon.
- ################################################################################
- def pbEnemyShouldMegaEvolve?(index)
- # Simple "always should if possible"
- return pbCanMegaEvolve?(index)
- end
- ################################################################################
- # Decide whether the opponent should use an item on the Pokémon.
- ################################################################################
- def pbEnemyShouldUseItem?(index)
- return false #by low
- item=pbEnemyItemToUse(index)
- if item>0
- pbRegisterItem(index,item,nil)
- return true
- end
- return false
- end
- def pbEnemyItemAlreadyUsed?(index,item,items)
- if @choices[1][0]==3 && @choices[1][1]==item
- qty=0
- for i in items
- qty+=1 if i==item
- end
- return true if qty<=1
- end
- return false
- end
- def pbEnemyItemToUse(index)
- return 0 if !@internalbattle
- items=pbGetOwnerItems(index)
- return 0 if !items
- battler=@battlers[index]
- return 0 if battler.fainted? ||
- battler.effects[PBEffects::Embargo]>0
- hashpitem=false
- for i in items
- next if pbEnemyItemAlreadyUsed?(index,i,items)
- if isConst?(i,PBItems,:POTION) ||
- isConst?(i,PBItems,:SUPERPOTION) ||
- isConst?(i,PBItems,:HYPERPOTION) ||
- isConst?(i,PBItems,:MAXPOTION) ||
- isConst?(i,PBItems,:FULLRESTORE)
- hashpitem=true
- end
- end
- for i in items
- next if pbEnemyItemAlreadyUsed?(index,i,items)
- if isConst?(i,PBItems,:FULLRESTORE)
- return i if battler.hp<=battler.totalhp/4
- return i if battler.hp<=battler.totalhp/2 && pbAIRandom(10)<3
- return i if battler.hp<=battler.totalhp*2/3 &&
- (battler.status>0 || battler.effects[PBEffects::Confusion]>0) &&
- pbAIRandom(10)<3
- elsif isConst?(i,PBItems,:POTION) ||
- isConst?(i,PBItems,:SUPERPOTION) ||
- isConst?(i,PBItems,:HYPERPOTION) ||
- isConst?(i,PBItems,:MAXPOTION)
- return i if battler.hp<=battler.totalhp/4
- return i if battler.hp<=battler.totalhp/2 && pbAIRandom(10)<3
- elsif isConst?(i,PBItems,:FULLHEAL)
- return i if !hashpitem &&
- (battler.status>0 || battler.effects[PBEffects::Confusion]>0)
- elsif isConst?(i,PBItems,:XATTACK) ||
- isConst?(i,PBItems,:XDEFEND) ||
- isConst?(i,PBItems,:XDEFENSE) ||
- isConst?(i,PBItems,:XSPEED) ||
- isConst?(i,PBItems,:XSPECIAL) ||
- isConst?(i,PBItems,:XSPATK) ||
- isConst?(i,PBItems,:XSPDEF) ||
- isConst?(i,PBItems,:XACCURACY)
- stat=0
- stat=PBStats::ATTACK if isConst?(i,PBItems,:XATTACK)
- stat=PBStats::DEFENSE if isConst?(i,PBItems,:XDEFEND)
- stat=PBStats::DEFENSE if isConst?(i,PBItems,:XDEFENSE)
- stat=PBStats::SPEED if isConst?(i,PBItems,:XSPEED)
- stat=PBStats::SPATK if isConst?(i,PBItems,:XSPECIAL)
- stat=PBStats::SPATK if isConst?(i,PBItems,:XSPATK)
- stat=PBStats::SPDEF if isConst?(i,PBItems,:XSPDEF)
- stat=PBStats::ACCURACY if isConst?(i,PBItems,:XACCURACY)
- if stat>0 && !battler.pbTooHigh?(stat)
- return i if pbAIRandom(10)<3-battler.stages[stat]
- end
- end
- end
- return 0
- end
- ################################################################################
- # Decide whether the opponent should switch Pokémon.
- ################################################################################
- def pbEnemyShouldWithdraw?(index)
- # if $INTERNAL && !pbIsOpposing?(index)
- # return pbEnemyShouldWithdrawOld?(index)
- # end
- return pbEnemyShouldWithdrawEx?(index,false)
- end
- def pbEnemyShouldWithdrawEx?(index,alwaysSwitch)
- return false if !@opponent
- shouldswitch=alwaysSwitch
- typecheck=false
- batonpass=-1
- movetype=-1
- skill=pbGetOwner(index).skill || 0
- if @opponent && !shouldswitch && @battlers[index].turncount>0
- if skill>=PBTrainerAI.highSkill
- opponent=@battlers[index].pbOppositeOpposing
- opponent=opponent.pbPartner if opponent.fainted?
- if !opponent.fainted? && opponent.lastMoveUsed>0 &&
- (opponent.level-@battlers[index].level).abs<=6
- move=PBMoveData.new(opponent.lastMoveUsed)
- typemod=pbTypeModifier(move.type,@battlers[index],@battlers[index])
- movetype=move.type
- if move.basedamage>70 && typemod>8
- shouldswitch=(pbAIRandom(100)<30)
- elsif move.basedamage>50 && typemod>8
- shouldswitch=(pbAIRandom(100)<20)
- end
- end
- end
- end
- if !pbCanChooseMove?(index,0,false) &&
- !pbCanChooseMove?(index,1,false) &&
- !pbCanChooseMove?(index,2,false) &&
- !pbCanChooseMove?(index,3,false) &&
- @battlers[index].turncount &&
- @battlers[index].turncount>5
- shouldswitch=true
- end
- if skill>=PBTrainerAI.highSkill && @battlers[index].effects[PBEffects::PerishSong]!=1
- for i in 0...4
- move=@battlers[index].moves[i]
- if move.id!=0 && pbCanChooseMove?(index,i,false) &&
- move.function==0xED # Baton Pass
- batonpass=i
- break
- end
- end
- end
- if skill>=PBTrainerAI.highSkill
- if @battlers[index].status==PBStatuses::POISON &&
- @battlers[index].statusCount>0
- toxicHP=(@battlers[index].totalhp/16)
- nextToxicHP=toxicHP*(@battlers[index].effects[PBEffects::Toxic]+1)
- if nextToxicHP>=@battlers[index].hp &&
- toxicHP<@battlers[index].hp && pbAIRandom(100)<80
- shouldswitch=true
- end
- end
- end
- if skill>=PBTrainerAI.mediumSkill
- if @battlers[index].effects[PBEffects::Encore]>0
- scoreSum=0
- scoreCount=0
- attacker=@battlers[index]
- encoreIndex=@battlers[index].effects[PBEffects::EncoreIndex]
- if !attacker.pbOpposing1.fainted?
- scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
- attacker,attacker.pbOpposing1,skill)
- scoreCount+=1
- end
- if !attacker.pbOpposing2.fainted?
- scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
- attacker,attacker.pbOpposing2,skill)
- scoreCount+=1
- end
- if scoreCount>0 && scoreSum/scoreCount<=20 && pbAIRandom(10)<8
- shouldswitch=true
- end
- end
- end
- if skill>=PBTrainerAI.highSkill
- if !@doublebattle && !@battlers[index].pbOppositeOpposing.fainted?
- opp=@battlers[index].pbOppositeOpposing
- if (opp.effects[PBEffects::HyperBeam]>0 ||
- (opp.hasWorkingAbility(:TRUANT) &&
- opp.effects[PBEffects::Truant])) && pbAIRandom(100)<80
- shouldswitch=false
- end
- end
- end
- if @rules["suddendeath"]
- if @battlers[index].hp<=(@battlers[index].totalhp/4) && pbAIRandom(10)<3 &&
- @battlers[index].turncount>0
- shouldswitch=true
- elsif @battlers[index].hp<=(@battlers[index].totalhp/2) && pbAIRandom(10)<8 &&
- @battlers[index].turncount>0
- shouldswitch=true
- end
- end
- if @battlers[index].effects[PBEffects::PerishSong]==1
- shouldswitch=true
- end
- if shouldswitch
- list=[]
- party=pbParty(index)
- for i in 0...party.length
- if pbCanSwitch?(index,i,false)
- # If perish count is 1, it may be worth it to switch
- # even with Spikes, since Perish Song's effect will end
- if @battlers[index].effects[PBEffects::PerishSong]!=1
- # Will contain effects that recommend against switching
- spikes=@battlers[index].pbOwnSide.effects[PBEffects::Spikes]
- if (spikes==1 && party[i].hp<=(party[i].totalhp/8)) ||
- (spikes==2 && party[i].hp<=(party[i].totalhp/6)) ||
- (spikes==3 && party[i].hp<=(party[i].totalhp/4))
- if !party[i].hasType?(:FLYING) &&
- !party[i].hasWorkingAbility(:LEVITATE)
- # Don't switch to this if too little HP
- next
- end
- end
- end
- if movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])==0
- weight=65
- if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)>8
- # Greater weight if new Pokemon's type is effective against opponent
- weight=85
- end
- if pbAIRandom(100)<weight
- list.unshift(i) # put this Pokemon first
- end
- elsif movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])<8
- weight=40
- if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)>8
- # Greater weight if new Pokemon's type is effective against opponent
- weight=60
- end
- if pbAIRandom(100)<weight
- list.unshift(i) # put this Pokemon first
- end
- else
- list.push(i) # put this Pokemon last
- end
- end
- end
- if list.length>0
- if batonpass!=-1
- if !pbRegisterMove(index,batonpass,false)
- return pbRegisterSwitch(index,list[0])
- end
- return true
- else
- return pbRegisterSwitch(index,list[0])
- end
- end
- end
- return false
- end
- def pbDefaultChooseNewEnemy(index,party)
- enemies=[]
- for i in 0..party.length-1
- if pbCanSwitchLax?(index,i,false)
- enemies.push(i)
- end
- end
- if enemies.length>0
- return pbChooseBestNewEnemy(index,party,enemies)
- end
- return -1
- end
- def pbChooseBestNewEnemy(index, party, enemies)
- return -1 if !enemies || enemies.length == 0
- $PokemonTemp = PokemonTemp.new if !$PokemonTemp
- o1 = @battlers[index].pbOpposing1
- o2 = @battlers[index].pbOpposing2
- o1 = nil if o1 && o1.fainted?
- o2 = nil if o2 && o2.fainted?
- best = -1
- bestSum = 0
- for e in enemies
- pkmn = party[e]
- sum = 0
- for move in pkmn.moves
- next if move.id == 0
- md = PBMoveData.new(move.id)
- next if md.basedamage == 0
- if o1
- sum += PBTypes.getCombinedEffectiveness(md.type, o1.type1, o1.type2)
- end
- if o2
- sum += PBTypes.getCombinedEffectiveness(md.type, o2.type1, o2.type2)
- end
- end
- if best == -1 || sum > bestSum
- best = e
- bestSum = sum
- end
- end
- return best
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement