TechSkylander1518

v17 PokeBattle_AI

Feb 2nd, 2023
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 152.37 KB | None | 0 0
  1. # AI skill levels:
  2. #           0:     Wild Pokémon
  3. #           1-31:  Basic trainer (young/inexperienced)
  4. #           32-47: Some skill
  5. #           48-99: High skill
  6. #           100+:  Gym Leaders, E4, Champion, highest level
  7. module PBTrainerAI
  8.   # Minimum skill level to be in each AI category
  9.   def PBTrainerAI.minimumSkill; 1; end
  10.   def PBTrainerAI.mediumSkill; 32; end
  11.   def PBTrainerAI.highSkill; 48; end
  12.   def PBTrainerAI.bestSkill; 100; end   # Gym Leaders, E4, Champion
  13. end
  14.  
  15.  
  16.  
  17. class PokeBattle_Battle
  18. ################################################################################
  19. # Get a score for each move being considered (trainer-owned Pokémon only).
  20. # Moves with higher scores are more likely to be chosen.
  21. ################################################################################
  22.   def pbGetMoveScore(move,attacker,opponent,skill=100)
  23.     skill=PBTrainerAI.minimumSkill if skill<PBTrainerAI.minimumSkill
  24.     score=100
  25.     opponent=attacker.pbOppositeOpposing if !opponent
  26.     opponent=opponent.pbPartner if opponent && opponent.fainted?
  27. ##### Alter score depending on the move's function code ########################
  28.     case move.function
  29.     when 0x00 # No extra effect
  30.     when 0x01
  31.       score-=95
  32.       if skill>=PBTrainerAI.highSkill
  33.         score=0
  34.       end
  35.     when 0x02 # Struggle
  36.     when 0x03
  37.       if opponent.pbCanSleep?(attacker,false)
  38.         score+=30
  39.         if skill>=PBTrainerAI.mediumSkill
  40.           score-=30 if opponent.effects[PBEffects::Yawn]>0
  41.         end
  42.         if skill>=PBTrainerAI.highSkill
  43.           score-=30 if opponent.hasWorkingAbility(:MARVELSCALE)
  44.         end
  45.         if skill>=PBTrainerAI.bestSkill
  46.           for i in opponent.moves
  47.             movedata=PBMoveData.new(i.id)
  48.             if movedata.function==0xB4 || # Sleep Talk
  49.                movedata.function==0x11    # Snore
  50.               score-=50
  51.               break
  52.             end
  53.           end
  54.         end
  55.       else
  56.         if skill>=PBTrainerAI.mediumSkill
  57.           score-=90 if move.basedamage==0
  58.         end
  59.       end
  60.     when 0x04
  61.       if opponent.effects[PBEffects::Yawn]>0 || !opponent.pbCanSleep?(attacker,false)
  62.         if skill>=PBTrainerAI.mediumSkill
  63.           score-=90
  64.         end
  65.       else
  66.         score+=30
  67.         if skill>=PBTrainerAI.highSkill
  68.           score-=30 if opponent.hasWorkingAbility(:MARVELSCALE)
  69.         end
  70.         if skill>=PBTrainerAI.bestSkill
  71.           for i in opponent.moves
  72.             movedata=PBMoveData.new(i.id)
  73.             if movedata.function==0xB4 || # Sleep Talk
  74.                movedata.function==0x11    # Snore
  75.               score-=50
  76.               break
  77.             end
  78.           end
  79.         end
  80.       end
  81.     when 0x05, 0x06, 0xBE
  82.       if opponent.pbCanPoison?(attacker,false)
  83.         score+=30
  84.         if skill>=PBTrainerAI.mediumSkill
  85.           score+=30 if opponent.hp<=opponent.totalhp/4
  86.           score+=50 if opponent.hp<=opponent.totalhp/8
  87.           score-=40 if opponent.effects[PBEffects::Yawn]>0
  88.         end
  89.         if skill>=PBTrainerAI.highSkill
  90.           score+=10 if pbRoughStat(opponent,PBStats::DEFENSE,skill)>100
  91.           score+=10 if pbRoughStat(opponent,PBStats::SPDEF,skill)>100
  92.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  93.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  94.           score-=40 if opponent.hasWorkingAbility(:TOXICBOOST)
  95.         end
  96.       else
  97.         if skill>=PBTrainerAI.mediumSkill
  98.           score-=90 if move.basedamage==0
  99.         end
  100.       end
  101.     when 0x07, 0x08, 0x09, 0xC5
  102.       if opponent.pbCanParalyze?(attacker,false) &&
  103.          !(skill>=PBTrainerAI.mediumSkill &&
  104.          isConst?(move.id,PBMoves,:THUNDERWAVE) &&
  105.          pbTypeModifier(move.type,attacker,opponent)==0)
  106.         score+=30
  107.         if skill>=PBTrainerAI.mediumSkill
  108.            aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  109.            ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  110.           if aspeed<ospeed
  111.             score+=30
  112.           elsif aspeed>ospeed
  113.             score-=40
  114.           end
  115.         end
  116.         if skill>=PBTrainerAI.highSkill
  117.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  118.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  119.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  120.         end
  121.       else
  122.         if skill>=PBTrainerAI.mediumSkill
  123.           score-=90 if move.basedamage==0
  124.         end
  125.       end
  126.     when 0x0A, 0x0B, 0xC6
  127.       if opponent.pbCanBurn?(attacker,false)
  128.         score+=30
  129.         if skill>=PBTrainerAI.highSkill
  130.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  131.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  132.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  133.           score-=40 if opponent.hasWorkingAbility(:FLAREBOOST)
  134.         end
  135.       else
  136.         if skill>=PBTrainerAI.mediumSkill
  137.           score-=90 if move.basedamage==0
  138.         end
  139.       end
  140.     when 0x0C, 0x0D, 0x0E
  141.       if opponent.pbCanFreeze?(attacker,false)
  142.         score+=30
  143.         if skill>=PBTrainerAI.highSkill
  144.           score-=20 if opponent.hasWorkingAbility(:MARVELSCALE)
  145.         end
  146.       else
  147.         if skill>=PBTrainerAI.mediumSkill
  148.           score-=90 if move.basedamage==0
  149.         end
  150.       end
  151.     when 0x0F
  152.       score+=30
  153.       if skill>=PBTrainerAI.highSkill
  154.         score+=30 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  155.                      opponent.effects[PBEffects::Substitute]==0
  156.       end
  157.     when 0x10
  158.       if skill>=PBTrainerAI.highSkill
  159.         score+=30 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  160.                      opponent.effects[PBEffects::Substitute]==0
  161.       end
  162.       score+=30 if opponent.effects[PBEffects::Minimize]
  163.     when 0x11
  164.       if attacker.status==PBStatuses::SLEEP
  165.         score+=100 # Because it can be used while asleep
  166.         if skill>=PBTrainerAI.highSkill
  167.           score+=30 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  168.                        opponent.effects[PBEffects::Substitute]==0
  169.         end
  170.       else
  171.         score-=90 # Because it will fail here
  172.         if skill>=PBTrainerAI.bestSkill
  173.           score=0
  174.         end
  175.       end
  176.     when 0x12
  177.       if attacker.turncount==0
  178.         if skill>=PBTrainerAI.highSkill
  179.           score+=30 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  180.                        opponent.effects[PBEffects::Substitute]==0
  181.         end
  182.       else
  183.         score-=90 # Because it will fail here
  184.         if skill>=PBTrainerAI.bestSkill
  185.           score=0
  186.         end
  187.       end
  188.     when 0x13, 0x14, 0x15
  189.       if opponent.pbCanConfuse?(attacker,false)
  190.         score+=30
  191.       else
  192.         if skill>=PBTrainerAI.mediumSkill
  193.           score-=90 if move.basedamage==0
  194.         end
  195.       end
  196.     when 0x16
  197.       canattract=true
  198.       agender=attacker.gender
  199.       ogender=opponent.gender
  200.       if agender==2 || ogender==2 || agender==ogender
  201.         score-=90; canattract=false
  202.       elsif opponent.effects[PBEffects::Attract]>=0
  203.         score-=80; canattract=false
  204.       elsif skill>=PBTrainerAI.bestSkill &&
  205.          opponent.hasWorkingAbility(:OBLIVIOUS)
  206.         score-=80; canattract=false
  207.       end
  208.       if skill>=PBTrainerAI.highSkill
  209.         if canattract && opponent.hasWorkingItem(:DESTINYKNOT) &&
  210.            attacker.pbCanAttract?(opponent,false)
  211.           score-=30
  212.         end
  213.       end
  214.     when 0x17
  215.       score+=30 if opponent.status==0
  216.     when 0x18
  217.       if attacker.status==PBStatuses::BURN
  218.         score+=40
  219.       elsif attacker.status==PBStatuses::POISON
  220.         score+=40
  221.         if skill>=PBTrainerAI.mediumSkill
  222.           if attacker.hp<attacker.totalhp/8
  223.             score+=60
  224.           elsif skill>=PBTrainerAI.highSkill &&
  225.              attacker.hp<(attacker.effects[PBEffects::Toxic]+1)*attacker.totalhp/16
  226.             score+=60
  227.           end
  228.         end
  229.       elsif attacker.status==PBStatuses::PARALYSIS
  230.         score+=40
  231.       else
  232.         score-=90
  233.       end
  234.     when 0x19
  235.       party=pbParty(attacker.index)
  236.       statuses=0
  237.       for i in 0...party.length
  238.         statuses+=1 if party[i] && party[i].status!=0
  239.       end
  240.       if statuses==0
  241.         score-=80
  242.       else
  243.         score+=20*statuses
  244.       end
  245.     when 0x1A
  246.       if attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  247.         score-=80
  248.       elsif attacker.status!=0
  249.         score-=40
  250.       else
  251.         score+=30
  252.       end
  253.     when 0x1B
  254.       if attacker.status==0
  255.         score-=90
  256.       else
  257.         score+=40
  258.       end
  259.     when 0x1C
  260.       if move.basedamage==0
  261.         if attacker.pbTooHigh?(PBStats::ATTACK)
  262.           score-=90
  263.         else
  264.           score-=attacker.stages[PBStats::ATTACK]*20
  265.           if skill>=PBTrainerAI.mediumSkill
  266.             hasphysicalattack=false
  267.             for thismove in attacker.moves
  268.               if thismove.id!=0 && thismove.basedamage>0 &&
  269.                  thismove.pbIsPhysical?(thismove.type)
  270.                 hasphysicalattack=true
  271.               end
  272.             end
  273.             if hasphysicalattack
  274.               score+=20
  275.             elsif skill>=PBTrainerAI.highSkill
  276.               score-=90
  277.             end
  278.           end
  279.         end
  280.       else
  281.         score+=20 if attacker.stages[PBStats::ATTACK]<0
  282.         if skill>=PBTrainerAI.mediumSkill
  283.           hasphysicalattack=false
  284.           for thismove in attacker.moves
  285.             if thismove.id!=0 && thismove.basedamage>0 &&
  286.                thismove.pbIsPhysical?(thismove.type)
  287.               hasphysicalattack=true
  288.             end
  289.           end
  290.           if hasphysicalattack
  291.             score+=20
  292.           end
  293.         end
  294.       end
  295.     when 0x1D, 0x1E, 0xC8
  296.       if move.basedamage==0
  297.         if attacker.pbTooHigh?(PBStats::DEFENSE)
  298.           score-=90
  299.         else
  300.           score-=attacker.stages[PBStats::DEFENSE]*20
  301.         end
  302.       else
  303.         score+=20 if attacker.stages[PBStats::DEFENSE]<0
  304.       end
  305.     when 0x1F
  306.       if move.basedamage==0
  307.         if attacker.pbTooHigh?(PBStats::SPEED)
  308.           score-=90
  309.         else
  310.           score-=attacker.stages[PBStats::SPEED]*10
  311.           if skill>=PBTrainerAI.highSkill
  312.             aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  313.             ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  314.             if aspeed<ospeed && aspeed*2>ospeed
  315.               score+=30
  316.             end
  317.           end
  318.         end
  319.       else
  320.         score+=20 if attacker.stages[PBStats::SPEED]<0
  321.       end
  322.     when 0x20
  323.       if move.basedamage==0
  324.         if attacker.pbTooHigh?(PBStats::SPATK)
  325.           score-=90
  326.         else
  327.           score-=attacker.stages[PBStats::SPATK]*20
  328.           if skill>=PBTrainerAI.mediumSkill
  329.             hasspecicalattack=false
  330.             for thismove in attacker.moves
  331.               if thismove.id!=0 && thismove.basedamage>0 &&
  332.                  thismove.pbIsSpecial?(thismove.type)
  333.                 hasspecicalattack=true
  334.               end
  335.             end
  336.             if hasspecicalattack
  337.               score+=20
  338.             elsif skill>=PBTrainerAI.highSkill
  339.               score-=90
  340.             end
  341.           end
  342.         end
  343.       else
  344.         score+=20 if attacker.stages[PBStats::SPATK]<0
  345.         if skill>=PBTrainerAI.mediumSkill
  346.           hasspecicalattack=false
  347.           for thismove in attacker.moves
  348.             if thismove.id!=0 && thismove.basedamage>0 &&
  349.                thismove.pbIsSpecial?(thismove.type)
  350.               hasspecicalattack=true
  351.             end
  352.           end
  353.           if hasspecicalattack
  354.             score+=20
  355.           end
  356.         end
  357.       end
  358.     when 0x21
  359.       foundmove=false
  360.       for i in 0...4
  361.         if isConst?(attacker.moves[i].type,PBTypes,:ELECTRIC) &&
  362.            attacker.moves[i].basedamage>0
  363.           foundmove=true
  364.           break
  365.         end
  366.       end
  367.       if move.basedamage==0
  368.         if attacker.pbTooHigh?(PBStats::SPDEF)
  369.           score-=90
  370.         else
  371.           score-=attacker.stages[PBStats::SPDEF]*20
  372.         end
  373.         score+=20 if foundmove
  374.       else
  375.         score+=20 if attacker.stages[PBStats::SPDEF]<0
  376.         score+=20 if foundmove
  377.       end
  378.     when 0x22
  379.       if move.basedamage==0
  380.         if attacker.pbTooHigh?(PBStats::EVASION)
  381.           score-=90
  382.         else
  383.           score-=attacker.stages[PBStats::EVASION]*10
  384.         end
  385.       else
  386.         score+=20 if attacker.stages[PBStats::EVASION]<0
  387.       end
  388.     when 0x23
  389.       if move.basedamage==0
  390.         if attacker.effects[PBEffects::FocusEnergy]>=2
  391.           score-=80
  392.         else
  393.           score+=30
  394.         end
  395.       else
  396.         score+=30 if attacker.effects[PBEffects::FocusEnergy]<2
  397.       end
  398.     when 0x24
  399.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  400.          attacker.pbTooHigh?(PBStats::DEFENSE)
  401.         score-=90
  402.       else
  403.         score-=attacker.stages[PBStats::ATTACK]*10
  404.         score-=attacker.stages[PBStats::DEFENSE]*10
  405.         if skill>=PBTrainerAI.mediumSkill
  406.           hasphysicalattack=false
  407.           for thismove in attacker.moves
  408.             if thismove.id!=0 && thismove.basedamage>0 &&
  409.                thismove.pbIsPhysical?(thismove.type)
  410.               hasphysicalattack=true
  411.             end
  412.           end
  413.           if hasphysicalattack
  414.             score+=20
  415.           elsif skill>=PBTrainerAI.highSkill
  416.             score-=90
  417.           end
  418.         end
  419.       end
  420.     when 0x25
  421.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  422.          attacker.pbTooHigh?(PBStats::DEFENSE) &&
  423.          attacker.pbTooHigh?(PBStats::ACCURACY)
  424.         score-=90
  425.       else
  426.         score-=attacker.stages[PBStats::ATTACK]*10
  427.         score-=attacker.stages[PBStats::DEFENSE]*10
  428.         score-=attacker.stages[PBStats::ACCURACY]*10
  429.         if skill>=PBTrainerAI.mediumSkill
  430.           hasphysicalattack=false
  431.           for thismove in attacker.moves
  432.             if thismove.id!=0 && thismove.basedamage>0 &&
  433.                thismove.pbIsPhysical?(thismove.type)
  434.               hasphysicalattack=true
  435.             end
  436.           end
  437.           if hasphysicalattack
  438.             score+=20
  439.           elsif skill>=PBTrainerAI.highSkill
  440.             score-=90
  441.           end
  442.         end
  443.       end
  444.     when 0x26
  445.       score+=40 if attacker.turncount==0 # Dragon Dance tends to be popular
  446.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  447.          attacker.pbTooHigh?(PBStats::SPEED)
  448.         score-=90
  449.       else
  450.         score-=attacker.stages[PBStats::ATTACK]*10
  451.         score-=attacker.stages[PBStats::SPEED]*10
  452.         if skill>=PBTrainerAI.mediumSkill
  453.           hasphysicalattack=false
  454.           for thismove in attacker.moves
  455.             if thismove.id!=0 && thismove.basedamage>0 &&
  456.                thismove.pbIsPhysical?(thismove.type)
  457.               hasphysicalattack=true
  458.             end
  459.           end
  460.           if hasphysicalattack
  461.             score+=20
  462.           elsif skill>=PBTrainerAI.highSkill
  463.             score-=90
  464.           end
  465.         end
  466.         if skill>=PBTrainerAI.highSkill
  467.           aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  468.           ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  469.           if aspeed<ospeed && aspeed*2>ospeed
  470.             score+=20
  471.           end
  472.         end
  473.       end
  474.     when 0x27, 0x28
  475.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  476.          attacker.pbTooHigh?(PBStats::SPATK)
  477.         score-=90
  478.       else
  479.         score-=attacker.stages[PBStats::ATTACK]*10
  480.         score-=attacker.stages[PBStats::SPATK]*10
  481.         if skill>=PBTrainerAI.mediumSkill
  482.           hasdamagingattack=false
  483.           for thismove in attacker.moves
  484.             if thismove.id!=0 && thismove.basedamage>0
  485.               hasdamagingattack=true; break
  486.             end
  487.           end
  488.           if hasdamagingattack
  489.             score+=20
  490.           elsif skill>=PBTrainerAI.highSkill
  491.             score-=90
  492.           end
  493.         end
  494.         if move.function==0x28 # Growth
  495.           score+=20 if pbWeather==PBWeather::SUNNYDAY
  496.         end
  497.       end
  498.     when 0x29
  499.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  500.          attacker.pbTooHigh?(PBStats::ACCURACY)
  501.         score-=90
  502.       else
  503.         score-=attacker.stages[PBStats::ATTACK]*10
  504.         score-=attacker.stages[PBStats::ACCURACY]*10
  505.         if skill>=PBTrainerAI.mediumSkill
  506.           hasphysicalattack=false
  507.           for thismove in attacker.moves
  508.             if thismove.id!=0 && thismove.basedamage>0 &&
  509.                thismove.pbIsPhysical?(thismove.type)
  510.               hasphysicalattack=true
  511.             end
  512.           end
  513.           if hasphysicalattack
  514.             score+=20
  515.           elsif skill>=PBTrainerAI.highSkill
  516.             score-=90
  517.           end
  518.         end
  519.       end
  520.     when 0x2A
  521.       if attacker.pbTooHigh?(PBStats::DEFENSE) &&
  522.          attacker.pbTooHigh?(PBStats::SPDEF)
  523.         score-=90
  524.       else
  525.         score-=attacker.stages[PBStats::DEFENSE]*10
  526.         score-=attacker.stages[PBStats::SPDEF]*10
  527.       end
  528.     when 0x2B
  529.       if attacker.pbTooHigh?(PBStats::SPEED) &&
  530.          attacker.pbTooHigh?(PBStats::SPATK) &&
  531.          attacker.pbTooHigh?(PBStats::SPDEF)
  532.         score-=90
  533.       else
  534.         score-=attacker.stages[PBStats::SPATK]*10
  535.         score-=attacker.stages[PBStats::SPDEF]*10
  536.         score-=attacker.stages[PBStats::SPEED]*10
  537.         if skill>=PBTrainerAI.mediumSkill
  538.           hasspecicalattack=false
  539.           for thismove in attacker.moves
  540.             if thismove.id!=0 && thismove.basedamage>0 &&
  541.                thismove.pbIsSpecial?(thismove.type)
  542.               hasspecicalattack=true
  543.             end
  544.           end
  545.           if hasspecicalattack
  546.             score+=20
  547.           elsif skill>=PBTrainerAI.highSkill
  548.             score-=90
  549.           end
  550.         end
  551.         if skill>=PBTrainerAI.highSkill
  552.           aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  553.           ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  554.           if aspeed<ospeed && aspeed*2>ospeed
  555.             score+=20
  556.           end
  557.         end
  558.       end
  559.     when 0x2C
  560.       if attacker.pbTooHigh?(PBStats::SPATK) &&
  561.          attacker.pbTooHigh?(PBStats::SPDEF)
  562.         score-=90
  563.       else
  564.         score+=40 if attacker.turncount==0 # Calm Mind tends to be popular
  565.         score-=attacker.stages[PBStats::SPATK]*10
  566.         score-=attacker.stages[PBStats::SPDEF]*10
  567.         if skill>=PBTrainerAI.mediumSkill
  568.           hasspecicalattack=false
  569.           for thismove in attacker.moves
  570.             if thismove.id!=0 && thismove.basedamage>0 &&
  571.                thismove.pbIsSpecial?(thismove.type)
  572.               hasspecicalattack=true
  573.             end
  574.           end
  575.           if hasspecicalattack
  576.             score+=20
  577.           elsif skill>=PBTrainerAI.highSkill
  578.             score-=90
  579.           end
  580.         end
  581.       end
  582.     when 0x2D
  583.       score+=10 if attacker.stages[PBStats::ATTACK]<0
  584.       score+=10 if attacker.stages[PBStats::DEFENSE]<0
  585.       score+=10 if attacker.stages[PBStats::SPEED]<0
  586.       score+=10 if attacker.stages[PBStats::SPATK]<0
  587.       score+=10 if attacker.stages[PBStats::SPDEF]<0
  588.       if skill>=PBTrainerAI.mediumSkill
  589.         hasdamagingattack=false
  590.         for thismove in attacker.moves
  591.           if thismove.id!=0 && thismove.basedamage>0
  592.             hasdamagingattack=true
  593.           end
  594.         end
  595.         if hasdamagingattack
  596.           score+=20
  597.         end
  598.       end
  599.     when 0x2E
  600.       if move.basedamage==0
  601.         if attacker.pbTooHigh?(PBStats::ATTACK)
  602.           score-=90
  603.         else
  604.           score+=40 if attacker.turncount==0
  605.           score-=attacker.stages[PBStats::ATTACK]*20
  606.           if skill>=PBTrainerAI.mediumSkill
  607.             hasphysicalattack=false
  608.             for thismove in attacker.moves
  609.               if thismove.id!=0 && thismove.basedamage>0 &&
  610.                  thismove.pbIsPhysical?(thismove.type)
  611.                 hasphysicalattack=true
  612.               end
  613.             end
  614.             if hasphysicalattack
  615.               score+=20
  616.             elsif skill>=PBTrainerAI.highSkill
  617.               score-=90
  618.             end
  619.           end
  620.         end
  621.       else
  622.         score+=10 if attacker.turncount==0
  623.         score+=20 if attacker.stages[PBStats::ATTACK]<0
  624.         if skill>=PBTrainerAI.mediumSkill
  625.           hasphysicalattack=false
  626.           for thismove in attacker.moves
  627.             if thismove.id!=0 && thismove.basedamage>0 &&
  628.                thismove.pbIsPhysical?(thismove.type)
  629.               hasphysicalattack=true
  630.             end
  631.           end
  632.           if hasphysicalattack
  633.             score+=20
  634.           end
  635.         end
  636.       end
  637.     when 0x2F
  638.       if move.basedamage==0
  639.         if attacker.pbTooHigh?(PBStats::DEFENSE)
  640.           score-=90
  641.         else
  642.           score+=40 if attacker.turncount==0
  643.           score-=attacker.stages[PBStats::DEFENSE]*20
  644.         end
  645.       else
  646.         score+=10 if attacker.turncount==0
  647.         score+=20 if attacker.stages[PBStats::DEFENSE]<0
  648.       end
  649.     when 0x30, 0x31
  650.       if move.basedamage==0
  651.         if attacker.pbTooHigh?(PBStats::SPEED)
  652.           score-=90
  653.         else
  654.           score+=20 if attacker.turncount==0
  655.           score-=attacker.stages[PBStats::SPEED]*10
  656.           if skill>=PBTrainerAI.highSkill
  657.             aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  658.             ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  659.             if aspeed<ospeed && aspeed*2>ospeed
  660.               score+=30
  661.             end
  662.           end
  663.         end
  664.       else
  665.         score+=10 if attacker.turncount==0
  666.         score+=20 if attacker.stages[PBStats::SPEED]<0
  667.       end
  668.     when 0x32
  669.       if move.basedamage==0
  670.         if attacker.pbTooHigh?(PBStats::SPATK)
  671.           score-=90
  672.         else
  673.           score+=40 if attacker.turncount==0
  674.           score-=attacker.stages[PBStats::SPATK]*20
  675.           if skill>=PBTrainerAI.mediumSkill
  676.             hasspecicalattack=false
  677.             for thismove in attacker.moves
  678.               if thismove.id!=0 && thismove.basedamage>0 &&
  679.                  thismove.pbIsSpecial?(thismove.type)
  680.                 hasspecicalattack=true
  681.               end
  682.             end
  683.             if hasspecicalattack
  684.               score+=20
  685.             elsif skill>=PBTrainerAI.highSkill
  686.               score-=90
  687.             end
  688.           end
  689.         end
  690.       else
  691.         score+=10 if attacker.turncount==0
  692.         score+=20 if attacker.stages[PBStats::SPATK]<0
  693.         if skill>=PBTrainerAI.mediumSkill
  694.           hasspecicalattack=false
  695.           for thismove in attacker.moves
  696.             if thismove.id!=0 && thismove.basedamage>0 &&
  697.                thismove.pbIsSpecial?(thismove.type)
  698.               hasspecicalattack=true
  699.             end
  700.           end
  701.           if hasspecicalattack
  702.             score+=20
  703.           end
  704.         end
  705.       end
  706.     when 0x33
  707.       if move.basedamage==0
  708.         if attacker.pbTooHigh?(PBStats::SPDEF)
  709.           score-=90
  710.         else
  711.           score+=40 if attacker.turncount==0
  712.           score-=attacker.stages[PBStats::SPDEF]*20
  713.         end
  714.       else
  715.         score+=10 if attacker.turncount==0
  716.         score+=20 if attacker.stages[PBStats::SPDEF]<0
  717.       end
  718.     when 0x34
  719.       if move.basedamage==0
  720.         if attacker.pbTooHigh?(PBStats::EVASION)
  721.           score-=90
  722.         else
  723.           score+=40 if attacker.turncount==0
  724.           score-=attacker.stages[PBStats::EVASION]*10
  725.         end
  726.       else
  727.         score+=10 if attacker.turncount==0
  728.         score+=20 if attacker.stages[PBStats::EVASION]<0
  729.       end
  730.     when 0x35
  731.       score-=attacker.stages[PBStats::ATTACK]*20
  732.       score-=attacker.stages[PBStats::SPEED]*20
  733.       score-=attacker.stages[PBStats::SPATK]*20
  734.       score+=attacker.stages[PBStats::DEFENSE]*10
  735.       score+=attacker.stages[PBStats::SPDEF]*10
  736.       if skill>=PBTrainerAI.mediumSkill
  737.         hasdamagingattack=false
  738.         for thismove in attacker.moves
  739.           if thismove.id!=0 && thismove.basedamage>0
  740.             hasdamagingattack=true
  741.           end
  742.         end
  743.         if hasdamagingattack
  744.           score+=20
  745.         end
  746.       end
  747.     when 0x36
  748.       if attacker.pbTooHigh?(PBStats::ATTACK) &&
  749.          attacker.pbTooHigh?(PBStats::SPEED)
  750.         score-=90
  751.       else
  752.         score-=attacker.stages[PBStats::ATTACK]*10
  753.         score-=attacker.stages[PBStats::SPEED]*10
  754.         if skill>=PBTrainerAI.mediumSkill
  755.           hasphysicalattack=false
  756.           for thismove in attacker.moves
  757.             if thismove.id!=0 && thismove.basedamage>0 &&
  758.                thismove.pbIsPhysical?(thismove.type)
  759.               hasphysicalattack=true
  760.             end
  761.           end
  762.           if hasphysicalattack
  763.             score+=20
  764.           elsif skill>=PBTrainerAI.highSkill
  765.             score-=90
  766.           end
  767.         end
  768.         if skill>=PBTrainerAI.highSkill
  769.           aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  770.           ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  771.           if aspeed<ospeed && aspeed*2>ospeed
  772.             score+=30
  773.           end
  774.         end
  775.       end
  776.     when 0x37
  777.       if opponent.pbTooHigh?(PBStats::ATTACK) &&
  778.          opponent.pbTooHigh?(PBStats::DEFENSE) &&
  779.          opponent.pbTooHigh?(PBStats::SPEED) &&
  780.          opponent.pbTooHigh?(PBStats::SPATK) &&
  781.          opponent.pbTooHigh?(PBStats::SPDEF) &&
  782.          opponent.pbTooHigh?(PBStats::ACCURACY) &&
  783.          opponent.pbTooHigh?(PBStats::EVASION)
  784.         score-=90
  785.       else
  786.         avstat=0
  787.         avstat-=opponent.stages[PBStats::ATTACK]
  788.         avstat-=opponent.stages[PBStats::DEFENSE]
  789.         avstat-=opponent.stages[PBStats::SPEED]
  790.         avstat-=opponent.stages[PBStats::SPATK]
  791.         avstat-=opponent.stages[PBStats::SPDEF]
  792.         avstat-=opponent.stages[PBStats::ACCURACY]
  793.         avstat-=opponent.stages[PBStats::EVASION]
  794.         avstat=(avstat/2).floor if avstat<0 # More chance of getting even better
  795.         score+=avstat*10
  796.       end
  797.     when 0x38
  798.       if move.basedamage==0
  799.         if attacker.pbTooHigh?(PBStats::DEFENSE)
  800.           score-=90
  801.         else
  802.           score+=40 if attacker.turncount==0
  803.           score-=attacker.stages[PBStats::DEFENSE]*30
  804.         end
  805.       else
  806.         score+=10 if attacker.turncount==0
  807.         score+=30 if attacker.stages[PBStats::DEFENSE]<0
  808.       end
  809.     when 0x39
  810.       if move.basedamage==0
  811.         if attacker.pbTooHigh?(PBStats::SPATK)
  812.           score-=90
  813.         else
  814.           score+=40 if attacker.turncount==0
  815.           score-=attacker.stages[PBStats::SPATK]*30
  816.           if skill>=PBTrainerAI.mediumSkill
  817.             hasspecicalattack=false
  818.             for thismove in attacker.moves
  819.               if thismove.id!=0 && thismove.basedamage>0 &&
  820.                  thismove.pbIsSpecial?(thismove.type)
  821.                 hasspecicalattack=true
  822.               end
  823.             end
  824.             if hasspecicalattack
  825.               score+=20
  826.             elsif skill>=PBTrainerAI.highSkill
  827.               score-=90
  828.             end
  829.           end
  830.         end
  831.       else
  832.         score+=10 if attacker.turncount==0
  833.         score+=30 if attacker.stages[PBStats::SPATK]<0
  834.         if skill>=PBTrainerAI.mediumSkill
  835.           hasspecicalattack=false
  836.           for thismove in attacker.moves
  837.             if thismove.id!=0 && thismove.basedamage>0 &&
  838.                thismove.pbIsSpecial?(thismove.type)
  839.               hasspecicalattack=true
  840.             end
  841.           end
  842.           if hasspecicalattack
  843.             score+=30
  844.           end
  845.         end
  846.       end
  847.     when 0x3A
  848.       if attacker.pbTooHigh?(PBStats::ATTACK) ||
  849.          attacker.hp<=attacker.totalhp/2
  850.         score-=100
  851.       else
  852.         score+=(6-attacker.stages[PBStats::ATTACK])*10
  853.         if skill>=PBTrainerAI.mediumSkill
  854.           hasphysicalattack=false
  855.           for thismove in attacker.moves
  856.             if thismove.id!=0 && thismove.basedamage>0 &&
  857.                thismove.pbIsPhysical?(thismove.type)
  858.               hasphysicalattack=true
  859.             end
  860.           end
  861.           if hasphysicalattack
  862.             score+=40
  863.           elsif skill>=PBTrainerAI.highSkill
  864.             score-=90
  865.           end
  866.         end
  867.       end
  868.     when 0x3B
  869.       avg=attacker.stages[PBStats::ATTACK]*10
  870.       avg+=attacker.stages[PBStats::DEFENSE]*10
  871.       score+=avg/2
  872.     when 0x3C
  873.       avg=attacker.stages[PBStats::DEFENSE]*10
  874.       avg+=attacker.stages[PBStats::SPDEF]*10
  875.       score+=avg/2
  876.     when 0x3D
  877.       avg=attacker.stages[PBStats::DEFENSE]*10
  878.       avg+=attacker.stages[PBStats::SPEED]*10
  879.       avg+=attacker.stages[PBStats::SPDEF]*10
  880.       score+=(avg/3).floor
  881.     when 0x3E
  882.       score+=attacker.stages[PBStats::SPEED]*10
  883.     when 0x3F
  884.       score+=attacker.stages[PBStats::SPATK]*10
  885.     when 0x40
  886.       if !opponent.pbCanConfuse?(attacker,false)
  887.         score-=90
  888.       else
  889.         score+=30 if opponent.stages[PBStats::SPATK]<0
  890.       end
  891.     when 0x41
  892.       if !opponent.pbCanConfuse?(attacker,false)
  893.         score-=90
  894.       else
  895.         score+=30 if opponent.stages[PBStats::ATTACK]<0
  896.       end
  897.     when 0x42
  898.       if move.basedamage==0
  899.         if !opponent.pbCanReduceStatStage?(PBStats::ATTACK,attacker)
  900.           score-=90
  901.         else
  902.           score+=opponent.stages[PBStats::ATTACK]*20
  903.           if skill>=PBTrainerAI.mediumSkill
  904.             hasphysicalattack=false
  905.             for thismove in opponent.moves
  906.               if thismove.id!=0 && thismove.basedamage>0 &&
  907.                  thismove.pbIsPhysical?(thismove.type)
  908.                 hasphysicalattack=true
  909.               end
  910.             end
  911.             if hasphysicalattack
  912.               score+=20
  913.             elsif skill>=PBTrainerAI.highSkill
  914.               score-=90
  915.             end
  916.           end
  917.         end
  918.       else
  919.         score+=20 if opponent.stages[PBStats::ATTACK]>0
  920.         if skill>=PBTrainerAI.mediumSkill
  921.           hasphysicalattack=false
  922.           for thismove in opponent.moves
  923.             if thismove.id!=0 && thismove.basedamage>0 &&
  924.                thismove.pbIsPhysical?(thismove.type)
  925.               hasphysicalattack=true
  926.             end
  927.           end
  928.           if hasphysicalattack
  929.             score+=20
  930.           end
  931.         end
  932.       end
  933.     when 0x43
  934.       if move.basedamage==0
  935.         if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE,attacker)
  936.           score-=90
  937.         else
  938.           score+=opponent.stages[PBStats::DEFENSE]*20
  939.         end
  940.       else
  941.         score+=20 if opponent.stages[PBStats::DEFENSE]>0
  942.       end
  943.     when 0x44
  944.       if move.basedamage==0
  945.         if !opponent.pbCanReduceStatStage?(PBStats::SPEED,attacker)
  946.           score-=90
  947.         else
  948.           score+=opponent.stages[PBStats::SPEED]*10
  949.           if skill>=PBTrainerAI.highSkill
  950.             aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  951.             ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  952.             if aspeed<ospeed && aspeed*2>ospeed
  953.               score+=30
  954.             end
  955.           end
  956.         end
  957.       else
  958.         score+=20 if attacker.stages[PBStats::SPEED]>0
  959.       end
  960.     when 0x45
  961.       if move.basedamage==0
  962.         if !opponent.pbCanReduceStatStage?(PBStats::SPATK,attacker)
  963.           score-=90
  964.         else
  965.           score+=attacker.stages[PBStats::SPATK]*20
  966.           if skill>=PBTrainerAI.mediumSkill
  967.             hasspecicalattack=false
  968.             for thismove in opponent.moves
  969.               if thismove.id!=0 && thismove.basedamage>0 &&
  970.                  thismove.pbIsSpecial?(thismove.type)
  971.                 hasspecicalattack=true
  972.               end
  973.             end
  974.             if hasspecicalattack
  975.               score+=20
  976.             elsif skill>=PBTrainerAI.highSkill
  977.               score-=90
  978.             end
  979.           end
  980.         end
  981.       else
  982.         score+=20 if attacker.stages[PBStats::SPATK]>0
  983.         if skill>=PBTrainerAI.mediumSkill
  984.           hasspecicalattack=false
  985.           for thismove in opponent.moves
  986.             if thismove.id!=0 && thismove.basedamage>0 &&
  987.                thismove.pbIsSpecial?(thismove.type)
  988.               hasspecicalattack=true
  989.             end
  990.           end
  991.           if hasspecicalattack
  992.             score+=20
  993.           end
  994.         end
  995.       end
  996.     when 0x46
  997.       if move.basedamage==0
  998.         if !opponent.pbCanReduceStatStage?(PBStats::SPDEF,attacker)
  999.           score-=90
  1000.         else
  1001.           score+=opponent.stages[PBStats::SPDEF]*20
  1002.         end
  1003.       else
  1004.         score+=20 if opponent.stages[PBStats::SPDEF]>0
  1005.       end
  1006.     when 0x47
  1007.       if move.basedamage==0
  1008.         if !opponent.pbCanReduceStatStage?(PBStats::ACCURACY,attacker)
  1009.           score-=90
  1010.         else
  1011.           score+=opponent.stages[PBStats::ACCURACY]*10
  1012.         end
  1013.       else
  1014.         score+=20 if opponent.stages[PBStats::ACCURACY]>0
  1015.       end
  1016.     when 0x48
  1017.       if move.basedamage==0
  1018.         if !opponent.pbCanReduceStatStage?(PBStats::EVASION,attacker)
  1019.           score-=90
  1020.         else
  1021.           score+=opponent.stages[PBStats::EVASION]*10
  1022.         end
  1023.       else
  1024.         score+=20 if opponent.stages[PBStats::EVASION]>0
  1025.       end
  1026.     when 0x49
  1027.       if move.basedamage==0
  1028.         if !opponent.pbCanReduceStatStage?(PBStats::EVASION,attacker)
  1029.           score-=90
  1030.         else
  1031.           score+=opponent.stages[PBStats::EVASION]*10
  1032.         end
  1033.       else
  1034.         score+=20 if opponent.stages[PBStats::EVASION]>0
  1035.       end
  1036.       score+=30 if opponent.pbOwnSide.effects[PBEffects::Reflect]>0 ||
  1037.                    opponent.pbOwnSide.effects[PBEffects::LightScreen]>0 ||
  1038.                    opponent.pbOwnSide.effects[PBEffects::Mist]>0 ||
  1039.                    opponent.pbOwnSide.effects[PBEffects::Safeguard]>0
  1040.       score-=30 if opponent.pbOwnSide.effects[PBEffects::Spikes]>0 ||
  1041.                    opponent.pbOwnSide.effects[PBEffects::ToxicSpikes]>0 ||
  1042.                    opponent.pbOwnSide.effects[PBEffects::StealthRock]
  1043.     when 0x4A
  1044.       avg=opponent.stages[PBStats::ATTACK]*10
  1045.       avg+=opponent.stages[PBStats::DEFENSE]*10
  1046.       score+=avg/2
  1047.     when 0x4B
  1048.       if move.basedamage==0
  1049.         if !opponent.pbCanReduceStatStage?(PBStats::ATTACK,attacker)
  1050.           score-=90
  1051.         else
  1052.           score+=40 if attacker.turncount==0
  1053.           score+=opponent.stages[PBStats::ATTACK]*20
  1054.           if skill>=PBTrainerAI.mediumSkill
  1055.             hasphysicalattack=false
  1056.             for thismove in opponent.moves
  1057.               if thismove.id!=0 && thismove.basedamage>0 &&
  1058.                  thismove.pbIsPhysical?(thismove.type)
  1059.                 hasphysicalattack=true
  1060.               end
  1061.             end
  1062.             if hasphysicalattack
  1063.               score+=20
  1064.             elsif skill>=PBTrainerAI.highSkill
  1065.               score-=90
  1066.             end
  1067.           end
  1068.         end
  1069.       else
  1070.         score+=10 if attacker.turncount==0
  1071.         score+=20 if opponent.stages[PBStats::ATTACK]>0
  1072.         if skill>=PBTrainerAI.mediumSkill
  1073.           hasphysicalattack=false
  1074.           for thismove in opponent.moves
  1075.             if thismove.id!=0 && thismove.basedamage>0 &&
  1076.                thismove.pbIsPhysical?(thismove.type)
  1077.               hasphysicalattack=true
  1078.             end
  1079.           end
  1080.           if hasphysicalattack
  1081.             score+=20
  1082.           end
  1083.         end
  1084.       end
  1085.     when 0x4C
  1086.       if move.basedamage==0
  1087.         if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE,attacker)
  1088.           score-=90
  1089.         else
  1090.           score+=40 if attacker.turncount==0
  1091.           score+=opponent.stages[PBStats::DEFENSE]*20
  1092.         end
  1093.       else
  1094.         score+=10 if attacker.turncount==0
  1095.         score+=20 if opponent.stages[PBStats::DEFENSE]>0
  1096.       end
  1097.     when 0x4D
  1098.       if move.basedamage==0
  1099.         if !opponent.pbCanReduceStatStage?(PBStats::SPEED,attacker)
  1100.           score-=90
  1101.         else
  1102.           score+=20 if attacker.turncount==0
  1103.           score+=opponent.stages[PBStats::SPEED]*20
  1104.           if skill>=PBTrainerAI.highSkill
  1105.             aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  1106.             ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  1107.             if aspeed<ospeed && aspeed*2>ospeed
  1108.               score+=30
  1109.             end
  1110.           end
  1111.         end
  1112.       else
  1113.         score+=10 if attacker.turncount==0
  1114.         score+=30 if opponent.stages[PBStats::SPEED]>0
  1115.       end
  1116.     when 0x4E
  1117.       if attacker.gender==2 || opponent.gender==2 ||
  1118.          attacker.gender==opponent.gender ||
  1119.          opponent.hasWorkingAbility(:OBLIVIOUS)
  1120.         score-=90
  1121.       elsif move.basedamage==0
  1122.         if !opponent.pbCanReduceStatStage?(PBStats::SPATK,attacker)
  1123.           score-=90
  1124.         else
  1125.           score+=40 if attacker.turncount==0
  1126.           score+=opponent.stages[PBStats::SPATK]*20
  1127.           if skill>=PBTrainerAI.mediumSkill
  1128.             hasspecicalattack=false
  1129.             for thismove in opponent.moves
  1130.               if thismove.id!=0 && thismove.basedamage>0 &&
  1131.                  thismove.pbIsSpecial?(thismove.type)
  1132.                 hasspecicalattack=true
  1133.               end
  1134.             end
  1135.             if hasspecicalattack
  1136.               score+=20
  1137.             elsif skill>=PBTrainerAI.highSkill
  1138.               score-=90
  1139.             end
  1140.           end
  1141.         end
  1142.       else
  1143.         score+=10 if attacker.turncount==0
  1144.         score+=20 if opponent.stages[PBStats::SPATK]>0
  1145.         if skill>=PBTrainerAI.mediumSkill
  1146.           hasspecicalattack=false
  1147.           for thismove in opponent.moves
  1148.             if thismove.id!=0 && thismove.basedamage>0 &&
  1149.                thismove.pbIsSpecial?(thismove.type)
  1150.               hasspecicalattack=true
  1151.             end
  1152.           end
  1153.           if hasspecicalattack
  1154.             score+=30
  1155.           end
  1156.         end
  1157.       end
  1158.     when 0x4F
  1159.       if move.basedamage==0
  1160.         if !opponent.pbCanReduceStatStage?(PBStats::SPDEF,attacker)
  1161.           score-=90
  1162.         else
  1163.           score+=40 if attacker.turncount==0
  1164.           score+=opponent.stages[PBStats::SPDEF]*20
  1165.         end
  1166.       else
  1167.         score+=10 if attacker.turncount==0
  1168.         score+=20 if opponent.stages[PBStats::SPDEF]>0
  1169.       end
  1170.     when 0x50
  1171.       if opponent.effects[PBEffects::Substitute]>0
  1172.         score-=90
  1173.       else
  1174.         anychange=false
  1175.         avg=opponent.stages[PBStats::ATTACK]; anychange=true if avg!=0
  1176.         avg+=opponent.stages[PBStats::DEFENSE]; anychange=true if avg!=0
  1177.         avg+=opponent.stages[PBStats::SPEED]; anychange=true if avg!=0
  1178.         avg+=opponent.stages[PBStats::SPATK]; anychange=true if avg!=0
  1179.         avg+=opponent.stages[PBStats::SPDEF]; anychange=true if avg!=0
  1180.         avg+=opponent.stages[PBStats::ACCURACY]; anychange=true if avg!=0
  1181.         avg+=opponent.stages[PBStats::EVASION]; anychange=true if avg!=0
  1182.         if anychange
  1183.           score+=avg*10
  1184.         else
  1185.           score-=90
  1186.         end
  1187.       end
  1188.     when 0x51
  1189.       if skill>=PBTrainerAI.mediumSkill
  1190.         stages=0
  1191.         for i in 0...4
  1192.           battler=@battlers[i]
  1193.           if attacker.pbIsOpposing?(i)
  1194.             stages+=battler.stages[PBStats::ATTACK]
  1195.             stages+=battler.stages[PBStats::DEFENSE]
  1196.             stages+=battler.stages[PBStats::SPEED]
  1197.             stages+=battler.stages[PBStats::SPATK]
  1198.             stages+=battler.stages[PBStats::SPDEF]
  1199.             stages+=battler.stages[PBStats::EVASION]
  1200.             stages+=battler.stages[PBStats::ACCURACY]
  1201.           else
  1202.             stages-=battler.stages[PBStats::ATTACK]
  1203.             stages-=battler.stages[PBStats::DEFENSE]
  1204.             stages-=battler.stages[PBStats::SPEED]
  1205.             stages-=battler.stages[PBStats::SPATK]
  1206.             stages-=battler.stages[PBStats::SPDEF]
  1207.             stages-=battler.stages[PBStats::EVASION]
  1208.             stages-=battler.stages[PBStats::ACCURACY]
  1209.           end
  1210.         end
  1211.         score+=stages*10
  1212.       end
  1213.     when 0x52
  1214.       if skill>=PBTrainerAI.mediumSkill
  1215.         aatk=attacker.stages[PBStats::ATTACK]
  1216.         aspa=attacker.stages[PBStats::SPATK]
  1217.         oatk=opponent.stages[PBStats::ATTACK]
  1218.         ospa=opponent.stages[PBStats::SPATK]
  1219.         if aatk>=oatk && aspa>=ospa
  1220.           score-=80
  1221.         else
  1222.           score+=(oatk-aatk)*10
  1223.           score+=(ospa-aspa)*10
  1224.         end
  1225.       else
  1226.         score-=50
  1227.       end
  1228.     when 0x53
  1229.       if skill>=PBTrainerAI.mediumSkill
  1230.         adef=attacker.stages[PBStats::DEFENSE]
  1231.         aspd=attacker.stages[PBStats::SPDEF]
  1232.         odef=opponent.stages[PBStats::DEFENSE]
  1233.         ospd=opponent.stages[PBStats::SPDEF]
  1234.         if adef>=odef && aspd>=ospd
  1235.           score-=80
  1236.         else
  1237.           score+=(odef-adef)*10
  1238.           score+=(ospd-aspd)*10
  1239.         end
  1240.       else
  1241.         score-=50
  1242.       end
  1243.     when 0x54
  1244.       if skill>=PBTrainerAI.mediumSkill
  1245.         astages=attacker.stages[PBStats::ATTACK]
  1246.         astages+=attacker.stages[PBStats::DEFENSE]
  1247.         astages+=attacker.stages[PBStats::SPEED]
  1248.         astages+=attacker.stages[PBStats::SPATK]
  1249.         astages+=attacker.stages[PBStats::SPDEF]
  1250.         astages+=attacker.stages[PBStats::EVASION]
  1251.         astages+=attacker.stages[PBStats::ACCURACY]
  1252.         ostages=opponent.stages[PBStats::ATTACK]
  1253.         ostages+=opponent.stages[PBStats::DEFENSE]
  1254.         ostages+=opponent.stages[PBStats::SPEED]
  1255.         ostages+=opponent.stages[PBStats::SPATK]
  1256.         ostages+=opponent.stages[PBStats::SPDEF]
  1257.         ostages+=opponent.stages[PBStats::EVASION]
  1258.         ostages+=opponent.stages[PBStats::ACCURACY]
  1259.         score+=(ostages-astages)*10
  1260.       else
  1261.         score-=50
  1262.       end
  1263.     when 0x55
  1264.       if skill>=PBTrainerAI.mediumSkill
  1265.         equal=true
  1266.         for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  1267.                  PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  1268.           stagediff=opponent.stages[i]-attacker.stages[i]
  1269.           score+=stagediff*10
  1270.           equal=false if stagediff!=0
  1271.         end
  1272.         score-=80 if equal
  1273.       else
  1274.         score-=50
  1275.       end
  1276.     when 0x56
  1277.       score-=80 if attacker.pbOwnSide.effects[PBEffects::Mist]>0
  1278.     when 0x57
  1279.       if skill>=PBTrainerAI.mediumSkill
  1280.         aatk=pbRoughStat(attacker,PBStats::ATTACK,skill)
  1281.         adef=pbRoughStat(attacker,PBStats::DEFENSE,skill)
  1282.         if aatk==adef ||
  1283.            attacker.effects[PBEffects::PowerTrick] # No flip-flopping
  1284.           score-=90
  1285.         elsif adef>aatk # Prefer a higher Attack
  1286.           score+=30
  1287.         else
  1288.           score-=30
  1289.         end
  1290.       else
  1291.         score-=30
  1292.       end
  1293.     when 0x58
  1294.       if skill>=PBTrainerAI.mediumSkill
  1295.         aatk=pbRoughStat(attacker,PBStats::ATTACK,skill)
  1296.         aspatk=pbRoughStat(attacker,PBStats::SPATK,skill)
  1297.         oatk=pbRoughStat(opponent,PBStats::ATTACK,skill)
  1298.         ospatk=pbRoughStat(opponent,PBStats::SPATK,skill)
  1299.         if aatk<oatk && aspatk<ospatk
  1300.           score+=50
  1301.         elsif (aatk+aspatk)<(oatk+ospatk)
  1302.           score+=30
  1303.         else
  1304.           score-=50
  1305.         end
  1306.       else
  1307.         score-=30
  1308.       end
  1309.     when 0x59
  1310.       if skill>=PBTrainerAI.mediumSkill
  1311.         adef=pbRoughStat(attacker,PBStats::DEFENSE,skill)
  1312.         aspdef=pbRoughStat(attacker,PBStats::SPDEF,skill)
  1313.         odef=pbRoughStat(opponent,PBStats::DEFENSE,skill)
  1314.         ospdef=pbRoughStat(opponent,PBStats::SPDEF,skill)
  1315.         if adef<odef && aspdef<ospdef
  1316.           score+=50
  1317.         elsif (adef+aspdef)<(odef+ospdef)
  1318.           score+=30
  1319.         else
  1320.           score-=50
  1321.         end
  1322.       else
  1323.         score-=30
  1324.       end
  1325.     when 0x5A
  1326.       if opponent.effects[PBEffects::Substitute]>0
  1327.         score-=90
  1328.       elsif attacker.hp>=(attacker.hp+opponent.hp)/2
  1329.         score-=90
  1330.       else
  1331.         score+=40
  1332.       end
  1333.     when 0x5B
  1334.       if attacker.pbOwnSide.effects[PBEffects::Tailwind]>0
  1335.         score-=90
  1336.       end
  1337.     when 0x5C
  1338.       blacklist=[
  1339.          0x02,   # Struggle
  1340.          0x14,   # Chatter
  1341.          0x5C,   # Mimic
  1342.          0x5D,   # Sketch
  1343.          0xB6    # Metronome
  1344.       ]
  1345.       if attacker.effects[PBEffects::Transform] ||
  1346.          opponent.lastMoveUsed<=0 ||
  1347.          isConst?(PBMoveData.new(opponent.lastMoveUsed).type,PBTypes,:SHADOW) ||
  1348.          blacklist.include?(PBMoveData.new(opponent.lastMoveUsed).function)
  1349.         score-=90
  1350.       end
  1351.       for i in attacker.moves
  1352.         if i.id==opponent.lastMoveUsed
  1353.           score-=90; break
  1354.         end
  1355.       end
  1356.     when 0x5D
  1357.       blacklist=[
  1358.          0x02,   # Struggle
  1359.          0x14,   # Chatter
  1360.          0x5D    # Sketch
  1361.       ]
  1362.       if attacker.effects[PBEffects::Transform] ||
  1363.          opponent.lastMoveUsedSketch<=0 ||
  1364.          isConst?(PBMoveData.new(opponent.lastMoveUsedSketch).type,PBTypes,:SHADOW) ||
  1365.          blacklist.include?(PBMoveData.new(opponent.lastMoveUsedSketch).function)
  1366.         score-=90
  1367.       end
  1368.       for i in attacker.moves
  1369.         if i.id==opponent.lastMoveUsedSketch
  1370.           score-=90; break
  1371.         end
  1372.       end
  1373.     when 0x5E
  1374.       if isConst?(attacker.ability,PBAbilities,:MULTITYPE)
  1375.         score-=90
  1376.       else
  1377.         types=[]
  1378.         for i in attacker.moves
  1379.           next if i.id==@id
  1380.           next if PBTypes.isPseudoType?(i.type)
  1381.           next if attacker.pbHasType?(i.type)
  1382.           found=false
  1383.           types.push(i.type) if !types.include?(i.type)
  1384.         end
  1385.         if types.length==0
  1386.           score-=90
  1387.         end
  1388.       end
  1389.     when 0x5F
  1390.       if isConst?(attacker.ability,PBAbilities,:MULTITYPE)
  1391.         score-=90
  1392.       elsif opponent.lastMoveUsed<=0 ||
  1393.          PBTypes.isPseudoType?(PBMoveData.new(opponent.lastMoveUsed).type)
  1394.         score-=90
  1395.       else
  1396.         atype=-1
  1397.         for i in opponent.moves
  1398.           if i.id==opponent.lastMoveUsed
  1399.             atype=i.pbType(move.type,attacker,opponent); break
  1400.           end
  1401.         end
  1402.         if atype<0
  1403.           score-=90
  1404.         else
  1405.           types=[]
  1406.           for i in 0..PBTypes.maxValue
  1407.             next if attacker.pbHasType?(i)
  1408.             types.push(i) if PBTypes.getEffectiveness(atype,i)<2
  1409.           end
  1410.           if types.length==0
  1411.             score-=90
  1412.           end
  1413.         end
  1414.       end
  1415.     when 0x60
  1416.       if isConst?(attacker.ability,PBAbilities,:MULTITYPE)
  1417.         score-=90
  1418.       elsif skill>=PBTrainerAI.mediumSkill
  1419.         envtypes=[
  1420.            :NORMAL, # None
  1421.            :GRASS,  # Grass
  1422.            :GRASS,  # Tall grass
  1423.            :WATER,  # Moving water
  1424.            :WATER,  # Still water
  1425.            :WATER,  # Underwater
  1426.            :ROCK,   # Rock
  1427.            :ROCK,   # Cave
  1428.            :GROUND  # Sand
  1429.         ]
  1430.         type=envtypes[@environment]
  1431.         score-=90 if attacker.pbHasType?(type)
  1432.       end
  1433.     when 0x61
  1434.       if opponent.effects[PBEffects::Substitute]>0 ||
  1435.          isConst?(opponent.ability,PBAbilities,:MULTITYPE)
  1436.         score-=90
  1437.       elsif opponent.pbHasType?(:WATER)
  1438.         score-=90
  1439.       end
  1440.     when 0x62
  1441.       if isConst?(attacker.ability,PBAbilities,:MULTITYPE)
  1442.         score-=90
  1443.       elsif attacker.pbHasType?(opponent.type1) &&
  1444.          attacker.pbHasType?(opponent.type2) &&
  1445.          opponent.pbHasType?(attacker.type1) &&
  1446.          opponent.pbHasType?(attacker.type2)
  1447.         score-=90
  1448.       end
  1449.     when 0x63
  1450.       if opponent.effects[PBEffects::Substitute]>0
  1451.         score-=90
  1452.       elsif skill>=PBTrainerAI.mediumSkill
  1453.         if isConst?(opponent.ability,PBAbilities,:MULTITYPE) ||
  1454.            isConst?(opponent.ability,PBAbilities,:SIMPLE) ||
  1455.            isConst?(opponent.ability,PBAbilities,:TRUANT)
  1456.           score-=90
  1457.         end
  1458.       end
  1459.     when 0x64
  1460.       if opponent.effects[PBEffects::Substitute]>0
  1461.         score-=90
  1462.       elsif skill>=PBTrainerAI.mediumSkill
  1463.         if isConst?(opponent.ability,PBAbilities,:MULTITYPE) ||
  1464.            isConst?(opponent.ability,PBAbilities,:INSOMNIA) ||
  1465.            isConst?(opponent.ability,PBAbilities,:TRUANT)
  1466.           score-=90
  1467.         end
  1468.       end
  1469.     when 0x65
  1470.       score-=40 # don't prefer this move
  1471.       if skill>=PBTrainerAI.mediumSkill
  1472.         if opponent.ability==0 ||
  1473.            attacker.ability==opponent.ability ||
  1474.            isConst?(attacker.ability,PBAbilities,:MULTITYPE) ||
  1475.            isConst?(opponent.ability,PBAbilities,:FLOWERGIFT) ||
  1476.            isConst?(opponent.ability,PBAbilities,:FORECAST) ||
  1477.            isConst?(opponent.ability,PBAbilities,:ILLUSION) ||
  1478.            isConst?(opponent.ability,PBAbilities,:IMPOSTER) ||
  1479.            isConst?(opponent.ability,PBAbilities,:MULTITYPE) ||
  1480.            isConst?(opponent.ability,PBAbilities,:TRACE) ||
  1481.            isConst?(opponent.ability,PBAbilities,:WONDERGUARD) ||
  1482.            isConst?(opponent.ability,PBAbilities,:ZENMODE)
  1483.           score-=90
  1484.         end
  1485.       end
  1486.       if skill>=PBTrainerAI.highSkill
  1487.         if isConst?(opponent.ability,PBAbilities,:TRUANT) &&
  1488.            attacker.pbIsOpposing?(opponent.index)
  1489.           score-=90
  1490.         elsif isConst?(opponent.ability,PBAbilities,:SLOWSTART) &&
  1491.            attacker.pbIsOpposing?(opponent.index)
  1492.           score-=90
  1493.         end
  1494.       end
  1495.     when 0x66
  1496.       score-=40 # don't prefer this move
  1497.       if opponent.effects[PBEffects::Substitute]>0
  1498.         score-=90
  1499.       elsif skill>=PBTrainerAI.mediumSkill
  1500.         if attacker.ability==0 ||
  1501.            attacker.ability==opponent.ability ||
  1502.            isConst?(opponent.ability,PBAbilities,:MULTITYPE) ||
  1503.            isConst?(opponent.ability,PBAbilities,:TRUANT) ||
  1504.            isConst?(attacker.ability,PBAbilities,:FLOWERGIFT) ||
  1505.            isConst?(attacker.ability,PBAbilities,:FORECAST) ||
  1506.            isConst?(attacker.ability,PBAbilities,:ILLUSION) ||
  1507.            isConst?(attacker.ability,PBAbilities,:IMPOSTER) ||
  1508.            isConst?(attacker.ability,PBAbilities,:MULTITYPE) ||
  1509.            isConst?(attacker.ability,PBAbilities,:TRACE) ||
  1510.            isConst?(attacker.ability,PBAbilities,:ZENMODE)
  1511.           score-=90
  1512.         end
  1513.         if skill>=PBTrainerAI.highSkill
  1514.           if isConst?(attacker.ability,PBAbilities,:TRUANT) &&
  1515.              attacker.pbIsOpposing?(opponent.index)
  1516.             score+=90
  1517.           elsif isConst?(attacker.ability,PBAbilities,:SLOWSTART) &&
  1518.              attacker.pbIsOpposing?(opponent.index)
  1519.             score+=90
  1520.           end
  1521.         end
  1522.       end
  1523.     when 0x67
  1524.       score-=40 # don't prefer this move
  1525.       if skill>=PBTrainerAI.mediumSkill
  1526.         if (attacker.ability==0 && opponent.ability==0) ||
  1527.            attacker.ability==opponent.ability ||
  1528.            isConst?(attacker.ability,PBAbilities,:ILLUSION) ||
  1529.            isConst?(opponent.ability,PBAbilities,:ILLUSION) ||
  1530.            isConst?(attacker.ability,PBAbilities,:MULTITYPE) ||
  1531.            isConst?(opponent.ability,PBAbilities,:MULTITYPE) ||
  1532.            isConst?(attacker.ability,PBAbilities,:WONDERGUARD) ||
  1533.            isConst?(opponent.ability,PBAbilities,:WONDERGUARD)
  1534.           score-=90
  1535.         end
  1536.       end
  1537.       if skill>=PBTrainerAI.highSkill
  1538.         if isConst?(opponent.ability,PBAbilities,:TRUANT) &&
  1539.            attacker.pbIsOpposing?(opponent.index)
  1540.           score-=90
  1541.         elsif isConst?(opponent.ability,PBAbilities,:SLOWSTART) &&
  1542.           attacker.pbIsOpposing?(opponent.index)
  1543.           score-=90
  1544.         end
  1545.       end
  1546.     when 0x68
  1547.       if opponent.effects[PBEffects::Substitute]>0 ||
  1548.          opponent.effects[PBEffects::GastroAcid]
  1549.         score-=90
  1550.       elsif skill>=PBTrainerAI.highSkill
  1551.         score-=90 if isConst?(opponent.ability,PBAbilities,:MULTITYPE)
  1552.         score-=90 if isConst?(opponent.ability,PBAbilities,:SLOWSTART)
  1553.         score-=90 if isConst?(opponent.ability,PBAbilities,:TRUANT)
  1554.       end
  1555.     when 0x69
  1556.       score-=70
  1557.     when 0x6A
  1558.       if opponent.hp<=20
  1559.         score+=80
  1560.       elsif opponent.level>=25
  1561.         score-=80 # Not useful against high-level Pokemon
  1562.       end
  1563.     when 0x6B
  1564.       score+=80 if opponent.hp<=40
  1565.     when 0x6C
  1566.       score-=50
  1567.       score+=(opponent.hp*100/opponent.totalhp).floor
  1568.     when 0x6D
  1569.       score+=80 if opponent.hp<=attacker.level
  1570.     when 0x6E
  1571.       if attacker.hp>=opponent.hp
  1572.         score-=90
  1573.       elsif attacker.hp*2<opponent.hp
  1574.         score+=50
  1575.       end
  1576.     when 0x6F
  1577.       score+=30 if opponent.hp<=attacker.level
  1578.     when 0x70
  1579.       score-=90 if opponent.hasWorkingAbility(:STURDY)
  1580.       score-=90 if opponent.level>attacker.level
  1581.     when 0x71
  1582.       if opponent.effects[PBEffects::HyperBeam]>0
  1583.         score-=90
  1584.       else
  1585.         attack=pbRoughStat(attacker,PBStats::ATTACK,skill)
  1586.         spatk=pbRoughStat(attacker,PBStats::SPATK,skill)
  1587.         if attack*1.5<spatk
  1588.           score-=60
  1589.         elsif skill>=PBTrainerAI.mediumSkill &&
  1590.            opponent.lastMoveUsed>0
  1591.           moveData=PBMoveData.new(opponent.lastMoveUsed)
  1592.           if moveData.basedamage>0 &&
  1593.              (USEMOVECATEGORY && moveData.category==2) ||
  1594.              (!USEMOVECATEGORY && PBTypes.isSpecialType?(moveData.type))
  1595.             score-=60
  1596.           end
  1597.         end
  1598.       end
  1599.     when 0x72
  1600.       if opponent.effects[PBEffects::HyperBeam]>0
  1601.         score-=90
  1602.       else
  1603.         attack=pbRoughStat(attacker,PBStats::ATTACK,skill)
  1604.         spatk=pbRoughStat(attacker,PBStats::SPATK,skill)
  1605.         if attack>spatk*1.5
  1606.           score-=60
  1607.         elsif skill>=PBTrainerAI.mediumSkill && opponent.lastMoveUsed>0
  1608.           moveData=PBMoveData.new(opponent.lastMoveUsed)
  1609.           if moveData.basedamage>0 &&
  1610.              (USEMOVECATEGORY && moveData.category==1) ||
  1611.              (!USEMOVECATEGORY && !PBTypes.isSpecialType?(moveData.type))
  1612.             score-=60
  1613.           end
  1614.         end
  1615.       end
  1616.     when 0x73
  1617.       score-=90 if opponent.effects[PBEffects::HyperBeam]>0
  1618.     when 0x74
  1619.       score+=10 if !opponent.pbPartner.fainted?
  1620.     when 0x75
  1621.     when 0x76
  1622.     when 0x77
  1623.     when 0x78
  1624.       if skill>=PBTrainerAI.highSkill
  1625.         score+=30 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  1626.                      opponent.effects[PBEffects::Substitute]==0
  1627.       end
  1628.     when 0x79
  1629.     when 0x7A
  1630.     when 0x7B
  1631.     when 0x7C
  1632.       score-=20 if opponent.status==PBStatuses::PARALYSIS # Will cure status
  1633.     when 0x7D
  1634.       score-=20 if opponent.status==PBStatuses::SLEEP && # Will cure status
  1635.                    opponent.statusCount>1
  1636.     when 0x7E
  1637.     when 0x7F
  1638.     when 0x80
  1639.     when 0x81
  1640.       attspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  1641.       oppspeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  1642.       score+=30 if oppspeed>attspeed
  1643.     when 0x82
  1644.       score+=20 if @doublebattle
  1645.     when 0x83
  1646.       if skill>=PBTrainerAI.mediumSkill
  1647.         score+=20 if @doublebattle && !attacker.pbPartner.fainted? &&
  1648.                      attacker.pbPartner.pbHasMove?(move.id)
  1649.       end
  1650.     when 0x84
  1651.       attspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  1652.       oppspeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  1653.       score+=30 if oppspeed>attspeed
  1654.     when 0x85
  1655.     when 0x86
  1656.     when 0x87
  1657.     when 0x88
  1658.     when 0x89
  1659.     when 0x8A
  1660.     when 0x8B
  1661.     when 0x8C
  1662.     when 0x8D
  1663.     when 0x8E
  1664.     when 0x8F
  1665.     when 0x90
  1666.     when 0x91
  1667.     when 0x92
  1668.     when 0x93
  1669.       score+=25 if attacker.effects[PBEffects::Rage]
  1670.     when 0x94
  1671.     when 0x95
  1672.     when 0x96
  1673.       score-=90 if !pbIsBerry?(attacker.item)
  1674.     when 0x97
  1675.     when 0x98
  1676.     when 0x99
  1677.     when 0x9A
  1678.     when 0x9B
  1679.     when 0x9C
  1680.       score-=90 if attacker.pbPartner.fainted?
  1681.     when 0x9D
  1682.       score-=90 if attacker.effects[PBEffects::MudSport]
  1683.     when 0x9E
  1684.       score-=90 if attacker.effects[PBEffects::WaterSport]
  1685.     when 0x9F
  1686.     when 0xA0
  1687.     when 0xA1
  1688.       score-=90 if attacker.pbOwnSide.effects[PBEffects::LuckyChant]>0
  1689.     when 0xA2
  1690.       score-=90 if attacker.pbOwnSide.effects[PBEffects::Reflect]>0
  1691.     when 0xA3
  1692.       score-=90 if attacker.pbOwnSide.effects[PBEffects::LightScreen]>0
  1693.     when 0xA4
  1694.     when 0xA5
  1695.     when 0xA6
  1696.       score-=90 if opponent.effects[PBEffects::Substitute]>0
  1697.       score-=90 if opponent.effects[PBEffects::LockOn]>0
  1698.     when 0xA7
  1699.       if opponent.effects[PBEffects::Foresight]
  1700.         score-=90
  1701.       elsif opponent.pbHasType?(:GHOST)
  1702.         score+=70
  1703.       elsif opponent.stages[PBStats::EVASION]<=0
  1704.         score-=60
  1705.       end
  1706.     when 0xA8
  1707.       if opponent.effects[PBEffects::MiracleEye]
  1708.         score-=90
  1709.       elsif opponent.pbHasType?(:DARK)
  1710.         score+=70
  1711.       elsif opponent.stages[PBStats::EVASION]<=0
  1712.         score-=60
  1713.       end
  1714.     when 0xA9
  1715.     when 0xAA
  1716.       if attacker.effects[PBEffects::ProtectRate]>1 ||
  1717.          opponent.effects[PBEffects::HyperBeam]>0
  1718.         score-=90
  1719.       else
  1720.         if skill>=PBTrainerAI.mediumSkill
  1721.           score-=(attacker.effects[PBEffects::ProtectRate]*40)
  1722.         end
  1723.         score+=50 if attacker.turncount==0
  1724.         score+=30 if opponent.effects[PBEffects::TwoTurnAttack]!=0
  1725.       end
  1726.     when 0xAB
  1727.     when 0xAC
  1728.     when 0xAD
  1729.     when 0xAE
  1730.       score-=40
  1731.       if skill>=PBTrainerAI.highSkill
  1732.         score-=100 if opponent.lastMoveUsed<=0 ||
  1733.                      (PBMoveData.new(opponent.lastMoveUsed).flags&0x10)==0 # flag e: Copyable by Mirror Move
  1734.       end
  1735.     when 0xAF
  1736.     when 0xB0
  1737.     when 0xB1
  1738.     when 0xB2
  1739.     when 0xB3
  1740.     when 0xB4
  1741.       if attacker.status==PBStatuses::SLEEP
  1742.         score+=200 # Because it can be used while asleep
  1743.       else
  1744.         score-=80
  1745.       end
  1746.     when 0xB5
  1747.     when 0xB6
  1748.     when 0xB7
  1749.       score-=90 if opponent.effects[PBEffects::Torment]
  1750.     when 0xB8
  1751.       score-=90 if attacker.effects[PBEffects::Imprison]
  1752.     when 0xB9
  1753.       score-=90 if opponent.effects[PBEffects::Disable]>0
  1754.     when 0xBA
  1755.       score-=90 if opponent.effects[PBEffects::Taunt]>0
  1756.     when 0xBB
  1757.       score-=90 if opponent.effects[PBEffects::HealBlock]>0
  1758.     when 0xBC
  1759.       aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  1760.       ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  1761.       if opponent.effects[PBEffects::Encore]>0
  1762.         score-=90
  1763.       elsif aspeed>ospeed
  1764.         if opponent.lastMoveUsed<=0
  1765.           score-=90
  1766.         else
  1767.           moveData=PBMoveData.new(opponent.lastMoveUsed)
  1768.           if moveData.basedamage==0 && (moveData.target==0x10 || moveData.target==0x20)
  1769.             score+=60
  1770.           elsif moveData.basedamage!=0 && moveData.target==0x00 &&
  1771.              pbTypeModifier(moveData.type,opponent,attacker)==0
  1772.             score+=60
  1773.           end
  1774.         end
  1775.       end
  1776.     when 0xBD
  1777.     when 0xBF
  1778.     when 0xC0
  1779.     when 0xC1
  1780.     when 0xC2
  1781.     when 0xC3
  1782.     when 0xC4
  1783.     when 0xC7
  1784.       score+=20 if attacker.effects[PBEffects::FocusEnergy]>0
  1785.       if skill>=PBTrainerAI.highSkill
  1786.         score+=20 if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  1787.                      opponent.effects[PBEffects::Substitute]==0
  1788.       end
  1789.     when 0xC9
  1790.     when 0xCA
  1791.     when 0xCB
  1792.     when 0xCC
  1793.     when 0xCD
  1794.     when 0xCE
  1795.     when 0xCF
  1796.       score+=40 if opponent.effects[PBEffects::MultiTurn]==0
  1797.     when 0xD0
  1798.       score+=40 if opponent.effects[PBEffects::MultiTurn]==0
  1799.     when 0xD1
  1800.     when 0xD2
  1801.     when 0xD3
  1802.     when 0xD4
  1803.       if attacker.hp<=attacker.totalhp/4
  1804.         score-=90
  1805.       elsif attacker.hp<=attacker.totalhp/2
  1806.         score-=50
  1807.       end
  1808.     when 0xD5, 0xD6
  1809.       if attacker.hp==attacker.totalhp
  1810.         score-=90
  1811.       else
  1812.         score+=50
  1813.         score-=(attacker.hp*100/attacker.totalhp)
  1814.       end
  1815.     when 0xD7
  1816.       score-=90 if attacker.effects[PBEffects::Wish]>0
  1817.     when 0xD8
  1818.       if attacker.hp==attacker.totalhp
  1819.         score-=90
  1820.       else
  1821.         case pbWeather
  1822.         when PBWeather::SUNNYDAY
  1823.           score+=30
  1824.         when PBWeather::RAINDANCE, PBWeather::SANDSTORM, PBWeather::HAIL
  1825.           score-=30
  1826.         end
  1827.         score+=50
  1828.         score-=(attacker.hp*100/attacker.totalhp)
  1829.       end
  1830.     when 0xD9
  1831.       if attacker.hp==attacker.totalhp || !attacker.pbCanSleep?(attacker,false,nil,true)
  1832.         score-=90
  1833.       else
  1834.         score+=70
  1835.         score-=(attacker.hp*140/attacker.totalhp)
  1836.         score+=30 if attacker.status!=0
  1837.       end
  1838.     when 0xDA
  1839.       score-=90 if attacker.effects[PBEffects::AquaRing]
  1840.     when 0xDB
  1841.       score-=90 if attacker.effects[PBEffects::Ingrain]
  1842.     when 0xDC
  1843.       if opponent.effects[PBEffects::LeechSeed]>=0
  1844.         score-=90
  1845.       elsif skill>=PBTrainerAI.mediumSkill && opponent.pbHasType?(:GRASS)
  1846.         score-=90
  1847.       else
  1848.         score+=60 if attacker.turncount==0
  1849.       end
  1850.     when 0xDD
  1851.       if skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:LIQUIDOOZE)
  1852.         score-=70
  1853.       else
  1854.         score+=20 if attacker.hp<=(attacker.totalhp/2)
  1855.       end
  1856.     when 0xDE
  1857.       if opponent.status!=PBStatuses::SLEEP
  1858.         score-=100
  1859.       elsif skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:LIQUIDOOZE)
  1860.         score-=70
  1861.       else
  1862.         score+=20 if attacker.hp<=(attacker.totalhp/2)
  1863.       end
  1864.     when 0xDF
  1865.       if attacker.pbIsOpposing?(opponent.index)
  1866.         score-=100
  1867.       else
  1868.         score+=20 if opponent.hp<(opponent.totalhp/2) &&
  1869.                      opponent.effects[PBEffects::Substitute]==0
  1870.       end
  1871.     when 0xE0
  1872.       reserves=attacker.pbNonActivePokemonCount
  1873.       foes=attacker.pbOppositeOpposing.pbNonActivePokemonCount
  1874.       if pbCheckGlobalAbility(:DAMP)
  1875.         score-=100
  1876.       elsif skill>=PBTrainerAI.mediumSkill && reserves==0 && foes>0
  1877.         score-=100 # don't want to lose
  1878.       elsif skill>=PBTrainerAI.highSkill && reserves==0 && foes==0
  1879.         score-=100 # don't want to draw
  1880.       else
  1881.         score-=(attacker.hp*100/attacker.totalhp)
  1882.       end
  1883.     when 0xE1
  1884.     when 0xE2
  1885.       if !opponent.pbCanReduceStatStage?(PBStats::ATTACK,attacker) &&
  1886.          !opponent.pbCanReduceStatStage?(PBStats::SPATK,attacker)
  1887.         score-=100
  1888.       elsif attacker.pbNonActivePokemonCount()==0
  1889.         score-=100
  1890.       else
  1891.         score+=(opponent.stages[PBStats::ATTACK]*10)
  1892.         score+=(opponent.stages[PBStats::SPATK]*10)
  1893.         score-=(attacker.hp*100/attacker.totalhp)
  1894.       end
  1895.     when 0xE3, 0xE4
  1896.       score-=70
  1897.     when 0xE5
  1898.       if attacker.pbNonActivePokemonCount()==0
  1899.         score-=90
  1900.       else
  1901.         score-=90 if opponent.effects[PBEffects::PerishSong]>0
  1902.       end
  1903.     when 0xE6
  1904.       score+=50
  1905.       score-=(attacker.hp*100/attacker.totalhp)
  1906.       score+=30 if attacker.hp<=(attacker.totalhp/10)
  1907.     when 0xE7
  1908.       score+=50
  1909.       score-=(attacker.hp*100/attacker.totalhp)
  1910.       score+=30 if attacker.hp<=(attacker.totalhp/10)
  1911.     when 0xE8
  1912.       score-=25 if attacker.hp>(attacker.totalhp/2)
  1913.       if skill>=PBTrainerAI.mediumSkill
  1914.         score-=90 if attacker.effects[PBEffects::ProtectRate]>1
  1915.         score-=90 if opponent.effects[PBEffects::HyperBeam]>0
  1916.       else
  1917.         score-=(attacker.effects[PBEffects::ProtectRate]*40)
  1918.       end
  1919.     when 0xE9
  1920.       if opponent.hp==1
  1921.         score-=90
  1922.       elsif opponent.hp<=(opponent.totalhp/8)
  1923.         score-=60
  1924.       elsif opponent.hp<=(opponent.totalhp/4)
  1925.         score-=30
  1926.       end
  1927.     when 0xEA
  1928.       score-=100 if @opponent
  1929.     when 0xEB
  1930.       if opponent.effects[PBEffects::Ingrain] ||
  1931.          (skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:SUCTIONCUPS))
  1932.         score-=90
  1933.       else
  1934.         party=pbParty(opponent.index)
  1935.         ch=0
  1936.         for i in 0...party.length
  1937.           ch+=1 if pbCanSwitchLax?(opponent.index,i,false)
  1938.         end
  1939.         score-=90 if ch==0
  1940.       end
  1941.       if score>20
  1942.         score+=50 if opponent.pbOwnSide.effects[PBEffects::Spikes]>0
  1943.         score+=50 if opponent.pbOwnSide.effects[PBEffects::ToxicSpikes]>0
  1944.         score+=50 if opponent.pbOwnSide.effects[PBEffects::StealthRock]
  1945.       end
  1946.     when 0xEC
  1947.       if !opponent.effects[PBEffects::Ingrain] &&
  1948.          !(skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:SUCTIONCUPS))
  1949.         score+=40 if opponent.pbOwnSide.effects[PBEffects::Spikes]>0
  1950.         score+=40 if opponent.pbOwnSide.effects[PBEffects::ToxicSpikes]>0
  1951.         score+=40 if opponent.pbOwnSide.effects[PBEffects::StealthRock]
  1952.       end
  1953.     when 0xED
  1954.       if !pbCanChooseNonActive?(attacker.index)
  1955.         score-=80
  1956.       else
  1957.         score-=40 if attacker.effects[PBEffects::Confusion]>0
  1958.         total=0
  1959.         total+=(attacker.stages[PBStats::ATTACK]*10)
  1960.         total+=(attacker.stages[PBStats::DEFENSE]*10)
  1961.         total+=(attacker.stages[PBStats::SPEED]*10)
  1962.         total+=(attacker.stages[PBStats::SPATK]*10)
  1963.         total+=(attacker.stages[PBStats::SPDEF]*10)
  1964.         total+=(attacker.stages[PBStats::EVASION]*10)
  1965.         total+=(attacker.stages[PBStats::ACCURACY]*10)
  1966.         if total<=0 || attacker.turncount==0
  1967.           score-=60
  1968.         else
  1969.           score+=total
  1970.           # special case: attacker has no damaging moves
  1971.           hasDamagingMove=false
  1972.           for m in attacker.moves
  1973.             if move.id!=0 && move.basedamage>0
  1974.               hasDamagingMove=true
  1975.             end
  1976.           end
  1977.           if !hasDamagingMove
  1978.             score+=75
  1979.           end
  1980.         end
  1981.       end
  1982.     when 0xEE
  1983.     when 0xEF
  1984.       score-=90 if opponent.effects[PBEffects::MeanLook]>=0
  1985.     when 0xF0
  1986.       if skill>=PBTrainerAI.highSkill
  1987.         score+=20 if opponent.item!=0
  1988.       end
  1989.     when 0xF1
  1990.       if skill>=PBTrainerAI.highSkill
  1991.         if attacker.item==0 && opponent.item!=0
  1992.           score+=40
  1993.         else
  1994.           score-=90
  1995.         end
  1996.       else
  1997.         score-=80
  1998.       end
  1999.     when 0xF2
  2000.       if attacker.item==0 && opponent.item==0
  2001.         score-=90
  2002.       elsif skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:STICKYHOLD)
  2003.         score-=90
  2004.       elsif attacker.hasWorkingItem(:FLAMEORB) ||
  2005.             attacker.hasWorkingItem(:TOXICORB) ||
  2006.             attacker.hasWorkingItem(:STICKYBARB) ||
  2007.             attacker.hasWorkingItem(:IRONBALL) ||
  2008.             attacker.hasWorkingItem(:CHOICEBAND) ||
  2009.             attacker.hasWorkingItem(:CHOICESCARF) ||
  2010.             attacker.hasWorkingItem(:CHOICESPECS)
  2011.         score+=50
  2012.       elsif attacker.item==0 && opponent.item!=0
  2013.         score-=30 if PBMoveData.new(attacker.lastMoveUsed).function==0xF2 # Trick/Switcheroo
  2014.       end
  2015.     when 0xF3
  2016.       if attacker.item==0 || opponent.item!=0
  2017.         score-=90
  2018.       else
  2019.         if attacker.hasWorkingItem(:FLAMEORB) ||
  2020.            attacker.hasWorkingItem(:TOXICORB) ||
  2021.            attacker.hasWorkingItem(:STICKYBARB) ||
  2022.            attacker.hasWorkingItem(:IRONBALL) ||
  2023.            attacker.hasWorkingItem(:CHOICEBAND) ||
  2024.            attacker.hasWorkingItem(:CHOICESCARF) ||
  2025.            attacker.hasWorkingItem(:CHOICESPECS)
  2026.           score+=50
  2027.         else
  2028.           score-=80
  2029.         end
  2030.       end
  2031.     when 0xF4, 0xF5
  2032.       if opponent.effects[PBEffects::Substitute]==0
  2033.         if skill>=PBTrainerAI.highSkill && pbIsBerry?(opponent.item)
  2034.           score+=30
  2035.         end
  2036.       end
  2037.     when 0xF6
  2038.       if attacker.pokemon.itemRecycle==0 || attacker.item!=0
  2039.         score-=80
  2040.       elsif attacker.pokemon.itemRecycle!=0
  2041.         score+=30
  2042.       end
  2043.     when 0xF7
  2044.       if attacker.item==0 ||
  2045.          pbIsUnlosableItem(attacker,attacker.item) ||
  2046.          pbIsPokeBall?(attacker.item) ||
  2047.          attacker.hasWorkingAbility(:KLUTZ) ||
  2048.          attacker.effects[PBEffects::Embargo]>0
  2049.         score-=90
  2050.       end
  2051.     when 0xF8
  2052.       score-=90 if opponent.effects[PBEffects::Embargo]>0
  2053.     when 0xF9
  2054.       if @field.effects[PBEffects::MagicRoom]>0
  2055.         score-=90
  2056.       else
  2057.         score+=30 if attacker.item==0 && opponent.item!=0
  2058.       end
  2059.     when 0xFA
  2060.       score-=25
  2061.     when 0xFB
  2062.       score-=30
  2063.     when 0xFC
  2064.       score-=40
  2065.     when 0xFD
  2066.       score-=30
  2067.       if opponent.pbCanParalyze?(attacker,false)
  2068.         score+=30
  2069.         if skill>=PBTrainerAI.mediumSkill
  2070.            aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  2071.            ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  2072.           if aspeed<ospeed
  2073.             score+=30
  2074.           elsif aspeed>ospeed
  2075.             score-=40
  2076.           end
  2077.         end
  2078.         if skill>=PBTrainerAI.highSkill
  2079.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  2080.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  2081.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  2082.         end
  2083.       end
  2084.     when 0xFE
  2085.       score-=30
  2086.       if opponent.pbCanBurn?(attacker,false)
  2087.         score+=30
  2088.         if skill>=PBTrainerAI.highSkill
  2089.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  2090.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  2091.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  2092.           score-=40 if opponent.hasWorkingAbility(:FLAREBOOST)
  2093.         end
  2094.       end
  2095.     when 0xFF
  2096.       if pbCheckGlobalAbility(:AIRLOCK) ||
  2097.          pbCheckGlobalAbility(:CLOUDNINE)
  2098.         score-=90
  2099.       elsif pbWeather==PBWeather::SUNNYDAY
  2100.         score-=90
  2101.       else
  2102.         for move in attacker.moves
  2103.           if move.id!=0 && move.basedamage>0 &&
  2104.              isConst?(move.type,PBTypes,:FIRE)
  2105.             score+=20
  2106.           end
  2107.         end
  2108.       end
  2109.     when 0x100
  2110.       if pbCheckGlobalAbility(:AIRLOCK) ||
  2111.          pbCheckGlobalAbility(:CLOUDNINE)
  2112.         score-=90
  2113.       elsif pbWeather==PBWeather::RAINDANCE
  2114.         score-=90
  2115.       else
  2116.         for move in attacker.moves
  2117.           if move.id!=0 && move.basedamage>0 &&
  2118.              isConst?(move.type,PBTypes,:WATER)
  2119.             score+=20
  2120.           end
  2121.         end
  2122.       end
  2123.     when 0x101
  2124.       if pbCheckGlobalAbility(:AIRLOCK) ||
  2125.          pbCheckGlobalAbility(:CLOUDNINE)
  2126.         score-=90
  2127.       elsif pbWeather==PBWeather::SANDSTORM
  2128.         score-=90
  2129.       end
  2130.     when 0x102
  2131.       if pbCheckGlobalAbility(:AIRLOCK) ||
  2132.          pbCheckGlobalAbility(:CLOUDNINE)
  2133.         score-=90
  2134.       elsif pbWeather==PBWeather::HAIL
  2135.         score-=90
  2136.       end
  2137.     when 0x103
  2138.       if attacker.pbOpposingSide.effects[PBEffects::Spikes]>=3
  2139.         score-=90
  2140.       elsif !pbCanChooseNonActive?(attacker.pbOpposing1.index) &&
  2141.             !pbCanChooseNonActive?(attacker.pbOpposing2.index)
  2142.         # Opponent can't switch in any Pokemon
  2143.         score-=90
  2144.       else
  2145.         score+=5*attacker.pbOppositeOpposing.pbNonActivePokemonCount()
  2146.         score+=[40,26,13][attacker.pbOpposingSide.effects[PBEffects::Spikes]]
  2147.       end
  2148.     when 0x104
  2149.       if attacker.pbOpposingSide.effects[PBEffects::ToxicSpikes]>=2
  2150.         score-=90
  2151.       elsif !pbCanChooseNonActive?(attacker.pbOpposing1.index) &&
  2152.             !pbCanChooseNonActive?(attacker.pbOpposing2.index)
  2153.         # Opponent can't switch in any Pokemon
  2154.         score-=90
  2155.       else
  2156.         score+=4*attacker.pbOppositeOpposing.pbNonActivePokemonCount()
  2157.         score+=[26,13][attacker.pbOpposingSide.effects[PBEffects::ToxicSpikes]]
  2158.       end
  2159.     when 0x105
  2160.       if attacker.pbOpposingSide.effects[PBEffects::StealthRock]
  2161.         score-=90
  2162.       elsif !pbCanChooseNonActive?(attacker.pbOpposing1.index) &&
  2163.             !pbCanChooseNonActive?(attacker.pbOpposing2.index)
  2164.         # Opponent can't switch in any Pokemon
  2165.         score-=90
  2166.       else
  2167.         score+=5*attacker.pbOppositeOpposing.pbNonActivePokemonCount()
  2168.       end
  2169.     when 0x106
  2170.     when 0x107
  2171.     when 0x108
  2172.     when 0x109
  2173.     when 0x10A
  2174.       score+=20 if attacker.pbOpposingSide.effects[PBEffects::Reflect]>0
  2175.       score+=20 if attacker.pbOpposingSide.effects[PBEffects::LightScreen]>0
  2176.     when 0x10B
  2177.       score+=10*(attacker.stages[PBStats::ACCURACY]-opponent.stages[PBStats::EVASION])
  2178.     when 0x10C
  2179.       if attacker.effects[PBEffects::Substitute]>0
  2180.         score-=90
  2181.       elsif attacker.hp<=(attacker.totalhp/4)
  2182.         score-=90
  2183.       end
  2184.     when 0x10D
  2185.       if attacker.pbHasType?(:GHOST)
  2186.         if opponent.effects[PBEffects::Curse]
  2187.           score-=90
  2188.         elsif attacker.hp<=(attacker.totalhp/2)
  2189.           if attacker.pbNonActivePokemonCount()==0
  2190.             score-=90
  2191.           else
  2192.             score-=50
  2193.             score-=30 if @shiftStyle
  2194.           end
  2195.         end
  2196.       else
  2197.         avg=(attacker.stages[PBStats::SPEED]*10)
  2198.         avg-=(attacker.stages[PBStats::ATTACK]*10)
  2199.         avg-=(attacker.stages[PBStats::DEFENSE]*10)
  2200.         score+=avg/3
  2201.       end
  2202.     when 0x10E
  2203.       score-=40
  2204.     when 0x10F
  2205.       if opponent.effects[PBEffects::Nightmare] ||
  2206.          opponent.effects[PBEffects::Substitute]>0
  2207.         score-=90
  2208.       elsif opponent.status!=PBStatuses::SLEEP
  2209.         score-=90
  2210.       else
  2211.         score-=90 if opponent.statusCount<=1
  2212.         score+=50 if opponent.statusCount>3
  2213.       end
  2214.     when 0x110
  2215.       score+=30 if attacker.effects[PBEffects::MultiTurn]>0
  2216.       score+=30 if attacker.effects[PBEffects::LeechSeed]>=0
  2217.       if attacker.pbNonActivePokemonCount()>0
  2218.         score+=80 if attacker.pbOwnSide.effects[PBEffects::Spikes]>0
  2219.         score+=80 if attacker.pbOwnSide.effects[PBEffects::ToxicSpikes]>0
  2220.         score+=80 if attacker.pbOwnSide.effects[PBEffects::StealthRock]
  2221.       end
  2222.     when 0x111
  2223.       if opponent.effects[PBEffects::FutureSight]>0
  2224.         score-=100
  2225.       elsif attacker.pbNonActivePokemonCount()==0
  2226.         # Future Sight tends to be wasteful if down to last Pokemon
  2227.         score-=70
  2228.       end
  2229.     when 0x112
  2230.       avg=0
  2231.       avg-=(attacker.stages[PBStats::DEFENSE]*10)
  2232.       avg-=(attacker.stages[PBStats::SPDEF]*10)
  2233.       score+=avg/2
  2234.       if attacker.effects[PBEffects::Stockpile]>=3
  2235.         score-=80
  2236.       else
  2237.         # More preferable if user also has Spit Up/Swallow
  2238.         for move in attacker.moves
  2239.           if move.function==0x113 || move.function==0x114 # Spit Up, Swallow
  2240.             score+=20; break
  2241.           end
  2242.         end
  2243.       end
  2244.     when 0x113
  2245.       score-=100 if attacker.effects[PBEffects::Stockpile]==0
  2246.     when 0x114
  2247.       if attacker.effects[PBEffects::Stockpile]==0
  2248.         score-=90
  2249.       elsif attacker.hp==attacker.totalhp
  2250.         score-=90
  2251.       else
  2252.         mult=[0,25,50,100][attacker.effects[PBEffects::Stockpile]]
  2253.         score+=mult
  2254.         score-=(attacker.hp*mult*2/attacker.totalhp)
  2255.       end
  2256.     when 0x115
  2257.       score+=50 if opponent.effects[PBEffects::HyperBeam]>0
  2258.       score-=35 if opponent.hp<=(opponent.totalhp/2) # If opponent is weak, no
  2259.       score-=70 if opponent.hp<=(opponent.totalhp/4) # need to risk this move
  2260.     when 0x116
  2261.     when 0x117
  2262.       if !@doublebattle
  2263.         score-=100
  2264.       elsif attacker.pbPartner.fainted?
  2265.         score-=90
  2266.       end
  2267.     when 0x118
  2268.       if @field.effects[PBEffects::Gravity]>0
  2269.         score-=90
  2270.       elsif skill>=PBTrainerAI.mediumSkill
  2271.         score-=30
  2272.         score-=20 if attacker.effects[PBEffects::SkyDrop]
  2273.         score-=20 if attacker.effects[PBEffects::MagnetRise]>0
  2274.         score-=20 if attacker.effects[PBEffects::Telekinesis]>0
  2275.         score-=20 if attacker.pbHasType?(:FLYING)
  2276.         score-=20 if attacker.hasWorkingAbility(:LEVITATE)
  2277.         score-=20 if attacker.hasWorkingItem(:AIRBALLOON)
  2278.         score+=20 if opponent.effects[PBEffects::SkyDrop]
  2279.         score+=20 if opponent.effects[PBEffects::MagnetRise]>0
  2280.         score+=20 if opponent.effects[PBEffects::Telekinesis]>0
  2281.         score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  2282.                      PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC || # Bounce
  2283.                      PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCE    # Sky Drop
  2284.         score+=20 if opponent.pbHasType?(:FLYING)
  2285.         score+=20 if opponent.hasWorkingAbility(:LEVITATE)
  2286.         score+=20 if opponent.hasWorkingItem(:AIRBALLOON)
  2287.       end
  2288.     when 0x119
  2289.       if attacker.effects[PBEffects::MagnetRise]>0 ||
  2290.          attacker.effects[PBEffects::Ingrain] ||
  2291.          attacker.effects[PBEffects::SmackDown]
  2292.         score-=90
  2293.       end
  2294.     when 0x11A
  2295.       if opponent.effects[PBEffects::Telekinesis]>0 ||
  2296.          opponent.effects[PBEffects::Ingrain] ||
  2297.          opponent.effects[PBEffects::SmackDown]
  2298.         score-=90
  2299.       end
  2300.     when 0x11B
  2301.     when 0x11C
  2302.       if skill>=PBTrainerAI.mediumSkill
  2303.         score+=20 if opponent.effects[PBEffects::MagnetRise]>0
  2304.         score+=20 if opponent.effects[PBEffects::Telekinesis]>0
  2305.         score+=20 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  2306.                      PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC    # Bounce
  2307.         score+=20 if opponent.pbHasType?(:FLYING)
  2308.         score+=20 if opponent.hasWorkingAbility(:LEVITATE)
  2309.         score+=20 if opponent.hasWorkingItem(:AIRBALLOON)
  2310.       end
  2311.     when 0x11D
  2312.     when 0x11E
  2313.     when 0x11F
  2314.     when 0x120
  2315.     when 0x121
  2316.     when 0x122
  2317.     when 0x123
  2318.       if !opponent.pbHasType?(attacker.type1) &&
  2319.          !opponent.pbHasType?(attacker.type2)
  2320.         score-=90
  2321.       end
  2322.     when 0x124
  2323.     when 0x125
  2324.     when 0x126
  2325.       score+=20 # Shadow moves are more preferable
  2326.     when 0x127
  2327.       score+=20 # Shadow moves are more preferable
  2328.       if opponent.pbCanParalyze?(attacker,false)
  2329.         score+=30
  2330.         if skill>=PBTrainerAI.mediumSkill
  2331.            aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  2332.            ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  2333.           if aspeed<ospeed
  2334.             score+=30
  2335.           elsif aspeed>ospeed
  2336.             score-=40
  2337.           end
  2338.         end
  2339.         if skill>=PBTrainerAI.highSkill
  2340.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  2341.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  2342.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  2343.         end
  2344.       end
  2345.     when 0x128
  2346.       score+=20 # Shadow moves are more preferable
  2347.       if opponent.pbCanBurn?(attacker,false)
  2348.         score+=30
  2349.         if skill>=PBTrainerAI.highSkill
  2350.           score-=40 if opponent.hasWorkingAbility(:GUTS)
  2351.           score-=40 if opponent.hasWorkingAbility(:MARVELSCALE)
  2352.           score-=40 if opponent.hasWorkingAbility(:QUICKFEET)
  2353.           score-=40 if opponent.hasWorkingAbility(:FLAREBOOST)
  2354.         end
  2355.       end
  2356.     when 0x129
  2357.       score+=20 # Shadow moves are more preferable
  2358.       if opponent.pbCanFreeze?(attacker,false)
  2359.         score+=30
  2360.         if skill>=PBTrainerAI.highSkill
  2361.           score-=20 if opponent.hasWorkingAbility(:MARVELSCALE)
  2362.         end
  2363.       end
  2364.     when 0x12A
  2365.       score+=20 # Shadow moves are more preferable
  2366.       if opponent.pbCanConfuse?(attacker,false)
  2367.         score+=30
  2368.       else
  2369.         if skill>=PBTrainerAI.mediumSkill
  2370.           score-=90
  2371.         end
  2372.       end
  2373.     when 0x12B
  2374.       score+=20 # Shadow moves are more preferable
  2375.       if !opponent.pbCanReduceStatStage?(PBStats::DEFENSE,attacker)
  2376.         score-=90
  2377.       else
  2378.         score+=40 if attacker.turncount==0
  2379.         score+=opponent.stages[PBStats::DEFENSE]*20
  2380.       end
  2381.     when 0x12C
  2382.       score+=20 # Shadow moves are more preferable
  2383.       if !opponent.pbCanReduceStatStage?(PBStats::EVASION,attacker)
  2384.         score-=90
  2385.       else
  2386.         score+=opponent.stages[PBStats::EVASION]*15
  2387.       end
  2388.     when 0x12D
  2389.       score+=20 # Shadow moves are more preferable
  2390.     when 0x12E
  2391.       score+=20 # Shadow moves are more preferable
  2392.       score+=20 if opponent.hp>=(opponent.totalhp/2)
  2393.       score-=20 if attacker.hp<(attacker.hp/2)
  2394.     when 0x12F
  2395.       score+=20 # Shadow moves are more preferable
  2396.       score-=110 if opponent.effects[PBEffects::MeanLook]>=0
  2397.     when 0x130
  2398.       score+=20 # Shadow moves are more preferable
  2399.       score-=40
  2400.     when 0x131
  2401.       score+=20 # Shadow moves are more preferable
  2402.       if pbCheckGlobalAbility(:AIRLOCK) ||
  2403.          pbCheckGlobalAbility(:CLOUDNINE)
  2404.         score-=90
  2405.       elsif pbWeather==PBWeather::SHADOWSKY
  2406.         score-=90
  2407.       end
  2408.     when 0x132
  2409.       score+=20 # Shadow moves are more preferable
  2410.       if opponent.pbOwnSide.effects[PBEffects::Reflect]>0 ||
  2411.          opponent.pbOwnSide.effects[PBEffects::LightScreen]>0 ||
  2412.          opponent.pbOwnSide.effects[PBEffects::Safeguard]>0
  2413.         score+=30
  2414.         score-=90 if attacker.pbOwnSide.effects[PBEffects::Reflect]>0 ||
  2415.                      attacker.pbOwnSide.effects[PBEffects::LightScreen]>0 ||
  2416.                      attacker.pbOwnSide.effects[PBEffects::Safeguard]>0
  2417.       else
  2418.         score-=110
  2419.       end
  2420.     when 0x133, 0x134
  2421.       score-=95
  2422.       if skill>=PBTrainerAI.highSkill
  2423.         score=0
  2424.       end
  2425.     when 0x135
  2426.       if opponent.pbCanFreeze?(attacker,false)
  2427.         score+=30
  2428.         if skill>=PBTrainerAI.highSkill
  2429.           score-=20 if opponent.hasWorkingAbility(:MARVELSCALE)
  2430.         end
  2431.       end
  2432.     when 0x136
  2433.       score+=20 if attacker.stages[PBStats::DEFENSE]<0
  2434.     when 0x137
  2435.       if attacker.pbTooHigh?(PBStats::DEFENSE) &&
  2436.          attacker.pbTooHigh?(PBStats::SPDEF) &&
  2437.          !attacker.pbPartner.fainted? &&
  2438.          attacker.pbPartner.pbTooHigh?(PBStats::DEFENSE) &&
  2439.          attacker.pbPartner.pbTooHigh?(PBStats::SPDEF)
  2440.         score-=90
  2441.       else
  2442.         score-=attacker.stages[PBStats::DEFENSE]*10
  2443.         score-=attacker.stages[PBStats::SPDEF]*10
  2444.         if !attacker.pbPartner.fainted?
  2445.           score-=attacker.pbPartner.stages[PBStats::DEFENSE]*10
  2446.           score-=attacker.pbPartner.stages[PBStats::SPDEF]*10
  2447.         end
  2448.       end
  2449.     when 0x138
  2450.       if !@doublebattle
  2451.         score-=100
  2452.       elsif attacker.pbPartner.fainted?
  2453.         score-=90
  2454.       else
  2455.         score-=attacker.pbPartner.stages[PBStats::SPDEF]*10
  2456.       end
  2457.     when 0x139
  2458.       if !opponent.pbCanReduceStatStage?(PBStats::ATTACK,attacker)
  2459.         score-=90
  2460.       else
  2461.         score+=opponent.stages[PBStats::ATTACK]*20
  2462.         if skill>=PBTrainerAI.mediumSkill
  2463.           hasphysicalattack=false
  2464.           for thismove in opponent.moves
  2465.             if thismove.id!=0 && thismove.basedamage>0 &&
  2466.                thismove.pbIsPhysical?(thismove.type)
  2467.               hasphysicalattack=true
  2468.             end
  2469.           end
  2470.           if hasphysicalattack
  2471.             score+=20
  2472.           elsif skill>=PBTrainerAI.highSkill
  2473.             score-=90
  2474.           end
  2475.         end
  2476.       end
  2477.     when 0x13A
  2478.       avg=opponent.stages[PBStats::ATTACK]*10
  2479.       avg+=opponent.stages[PBStats::SPATK]*10
  2480.       score+=avg/2
  2481.     when 0x13B
  2482.       if !isConst?(attacker.species,PBSpecies,:HOOPA) || attacker.form!=1
  2483.         score-=100
  2484.       else
  2485.         score+=20 if opponent.stages[PBStats::DEFENSE]>0
  2486.       end
  2487.     when 0x13C
  2488.       score+=20 if opponent.stages[PBStats::SPATK]>0
  2489.     when 0x13D
  2490.       if !opponent.pbCanReduceStatStage?(PBStats::SPATK,attacker)
  2491.         score-=90
  2492.       else
  2493.         score+=40 if attacker.turncount==0
  2494.         score+=opponent.stages[PBStats::SPATK]*20
  2495.       end
  2496.     when 0x13E
  2497.       count=0
  2498.       for i in 0...4
  2499.         battler=@battlers[i]
  2500.         if battler.pbHasType?(:GRASS) && !battler.isAirborne? &&
  2501.            (!battler.pbTooHigh?(PBStats::ATTACK) || !battler.pbTooHigh?(PBStats::SPATK))
  2502.           count+=1
  2503.           if attacker.pbIsOpposing?(battler)
  2504.             score-=20
  2505.           else
  2506.             score-=attacker.stages[PBStats::ATTACK]*10
  2507.             score-=attacker.stages[PBStats::SPATK]*10
  2508.           end
  2509.         end
  2510.       end
  2511.       score-=95 if count==0
  2512.     when 0x13F
  2513.       count=0
  2514.       for i in 0...4
  2515.         battler=@battlers[i]
  2516.         if battler.pbHasType?(:GRASS) && !battler.pbTooHigh?(PBStats::DEFENSE)
  2517.           count+=1
  2518.           if attacker.pbIsOpposing?(battler)
  2519.             score-=20
  2520.           else
  2521.             score-=attacker.stages[PBStats::DEFENSE]*10
  2522.           end
  2523.         end
  2524.       end
  2525.       score-=95 if count==0
  2526.     when 0x140
  2527.       count=0
  2528.       for i in 0...4
  2529.         battler=@battlers[i]
  2530.         if battler.status==PBStatuses::POISON &&
  2531.            (!battler.pbTooLow?(PBStats::ATTACK) ||
  2532.            !battler.pbTooLow?(PBStats::SPATK) ||
  2533.            !battler.pbTooLow?(PBStats::SPEED))
  2534.           count+=1
  2535.           if attacker.pbIsOpposing?(battler)
  2536.             score+=attacker.stages[PBStats::ATTACK]*10
  2537.             score+=attacker.stages[PBStats::SPATK]*10
  2538.             score+=attacker.stages[PBStats::SPEED]*10
  2539.           else
  2540.             score-=20
  2541.           end
  2542.         end
  2543.       end
  2544.       score-=95 if count==0
  2545.     when 0x141
  2546.       if opponent.effects[PBEffects::Substitute]>0
  2547.         score-=90
  2548.       else
  2549.         numpos=0; numneg=0
  2550.         for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  2551.                   PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  2552.           stat=opponent.stages[i]
  2553.           (stat>0) ? numpos+=stat : numneg+=stat
  2554.         end
  2555.         if numpos!=0 || numneg!=0
  2556.           score+=(numpos-numneg)*10
  2557.         else
  2558.           score-=95
  2559.         end
  2560.       end
  2561.     when 0x142
  2562.       if opponent.pbHasType?(:GHOST)
  2563.         score-=90
  2564.       end
  2565.     when 0x143
  2566.       if opponent.pbHasType?(:GRASS)
  2567.         score-=90
  2568.       end
  2569.     when 0x144
  2570.     when 0x145
  2571.       aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  2572.       ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  2573.       if aspeed>ospeed
  2574.         score-=90
  2575.       end
  2576.     when 0x146
  2577.     when 0x147
  2578.     when 0x148
  2579.       aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  2580.       ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  2581.       if aspeed>ospeed
  2582.         score-=90
  2583.       else
  2584.         score+=30 if opponent.pbHasMoveType?(:FIRE)
  2585.       end
  2586.     when 0x149
  2587.       if attacker.turncount==0
  2588.         score+=30
  2589.       else
  2590.         score-=90 # Because it will fail here
  2591.         score=0 if skill>=PBTrainerAI.bestSkill
  2592.       end
  2593.     when 0x14A
  2594.     when 0x14B, 0x14C
  2595.       if attacker.effects[PBEffects::ProtectRate]>1 ||
  2596.          opponent.effects[PBEffects::HyperBeam]>0
  2597.         score-=90
  2598.       else
  2599.         if skill>=PBTrainerAI.mediumSkill
  2600.           score-=(attacker.effects[PBEffects::ProtectRate]*40)
  2601.         end
  2602.         score+=50 if attacker.turncount==0
  2603.         score+=30 if opponent.effects[PBEffects::TwoTurnAttack]!=0
  2604.       end
  2605.     when 0x14D
  2606.     when 0x14E
  2607.       if attacker.pbTooHigh?(PBStats::SPATK) &&
  2608.          attacker.pbTooHigh?(PBStats::SPDEF) &&
  2609.          attacker.pbTooHigh?(PBStats::SPEED)
  2610.         score-=90
  2611.       else
  2612.         score-=attacker.stages[PBStats::SPATK]*10 # Only *10 isntead of *20
  2613.         score-=attacker.stages[PBStats::SPDEF]*10 # because two-turn attack
  2614.         score-=attacker.stages[PBStats::SPEED]*10
  2615.         if skill>=PBTrainerAI.mediumSkill
  2616.           hasspecialattack=false
  2617.           for thismove in attacker.moves
  2618.             if thismove.id!=0 && thismove.basedamage>0 &&
  2619.                thismove.pbIsSpecial?(thismove.type)
  2620.               hasspecialattack=true
  2621.             end
  2622.           end
  2623.           if hasspecialattack
  2624.             score+=20
  2625.           elsif skill>=PBTrainerAI.highSkill
  2626.             score-=90
  2627.           end
  2628.         end
  2629.         if skill>=PBTrainerAI.highSkill
  2630.           aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  2631.           ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  2632.           if aspeed<ospeed && aspeed*2>ospeed
  2633.             score+=30
  2634.           end
  2635.         end
  2636.       end
  2637.     when 0x14F
  2638.       if skill>=PBTrainerAI.highSkill && opponent.hasWorkingAbility(:LIQUIDOOZE)
  2639.         score-=80
  2640.       else
  2641.         score+=40 if attacker.hp<=(attacker.totalhp/2)
  2642.       end
  2643.     when 0x150
  2644.       score+=20 if !attacker.pbTooHigh?(PBStats::ATTACK) && opponent.hp<=(opponent.totalhp/4)
  2645.     when 0x151
  2646.       avg=opponent.stages[PBStats::ATTACK]*10
  2647.       avg+=opponent.stages[PBStats::SPATK]*10
  2648.       score+=avg/2
  2649.     when 0x152
  2650.     when 0x153
  2651.       score-=95 if opponent.pbOwnSide.effects[PBEffects::StickyWeb]
  2652.     when 0x154
  2653.     when 0x155
  2654.     when 0x156
  2655.     when 0x157
  2656.       score-=90
  2657.     when 0x158
  2658.       score-=90 if !attacker.pokemon || !attacker.pokemon.belch
  2659.     end
  2660.     # A score of 0 here means it should absolutely not be used
  2661.     return score if score<=0
  2662. ##### Other score modifications ################################################
  2663.     # Prefer damaging moves if AI has no more Pokémon
  2664.     if attacker.pbNonActivePokemonCount==0
  2665.       if skill>=PBTrainerAI.mediumSkill &&
  2666.          !(skill>=PBTrainerAI.highSkill && opponent.pbNonActivePokemonCount>0)
  2667.         if move.basedamage==0
  2668.           score/=1.5
  2669.         elsif opponent.hp<=opponent.totalhp/2
  2670.           score*=1.5
  2671.         end
  2672.       end
  2673.     end
  2674.     # Don't prefer attacking the opponent if they'd be semi-invulnerable
  2675.     if opponent.effects[PBEffects::TwoTurnAttack]>0 &&
  2676.        skill>=PBTrainerAI.highSkill
  2677.       invulmove=PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function
  2678.       if move.accuracy>0 &&   # Checks accuracy, i.e. targets opponent
  2679.          ([0xC9,0xCA,0xCB,0xCC,0xCD,0xCE].include?(invulmove) ||
  2680.          opponent.effects[PBEffects::SkyDrop]) &&
  2681.          attacker.pbSpeed>opponent.pbSpeed
  2682.         if skill>=PBTrainerAI.bestSkill   # Can get past semi-invulnerability
  2683.           miss=false
  2684.           case invulmove
  2685.           when 0xC9, 0xCC # Fly, Bounce
  2686.             miss=true unless move.function==0x08 ||  # Thunder
  2687.                              move.function==0x15 ||  # Hurricane
  2688.                              move.function==0x77 ||  # Gust
  2689.                              move.function==0x78 ||  # Twister
  2690.                              move.function==0x11B || # Sky Uppercut
  2691.                              move.function==0x11C || # Smack Down
  2692.                              isConst?(move.id,PBMoves,:WHIRLWIND)
  2693.           when 0xCA # Dig
  2694.             miss=true unless move.function==0x76 || # Earthquake
  2695.                              move.function==0x95    # Magnitude
  2696.           when 0xCB # Dive
  2697.             miss=true unless move.function==0x75 || # Surf
  2698.                              move.function==0xD0    # Whirlpool
  2699.           when 0xCD # Shadow Force
  2700.             miss=true
  2701.           when 0xCE # Sky Drop
  2702.             miss=true unless move.function==0x08 ||  # Thunder
  2703.                              move.function==0x15 ||  # Hurricane
  2704.                              move.function==0x77 ||  # Gust
  2705.                              move.function==0x78 ||  # Twister
  2706.                              move.function==0x11B || # Sky Uppercut
  2707.                              move.function==0x11C    # Smack Down
  2708.           when 0x14D # Phantom Force
  2709.             miss=true
  2710.           end
  2711.           if opponent.effects[PBEffects::SkyDrop]
  2712.             miss=true unless move.function==0x08 ||  # Thunder
  2713.                              move.function==0x15 ||  # Hurricane
  2714.                              move.function==0x77 ||  # Gust
  2715.                              move.function==0x78 ||  # Twister
  2716.                              move.function==0x11B || # Sky Uppercut
  2717.                              move.function==0x11C    # Smack Down
  2718.           end
  2719.           score-=80 if miss
  2720.         else
  2721.           score-=80
  2722.         end
  2723.       end
  2724.     end
  2725.     # Pick a good move for the Choice items
  2726.     if attacker.hasWorkingItem(:CHOICEBAND) ||
  2727.        attacker.hasWorkingItem(:CHOICESPECS) ||
  2728.        attacker.hasWorkingItem(:CHOICESCARF)
  2729.       if skill>=PBTrainerAI.mediumSkill
  2730.         if move.basedamage>=60
  2731.           score+=60
  2732.         elsif move.basedamage>0
  2733.           score+=30
  2734.         elsif move.function==0xF2 # Trick
  2735.           score+=70
  2736.         else
  2737.           score-=60
  2738.         end
  2739.       end
  2740.     end
  2741.     # If user has King's Rock, prefer moves that may cause flinching with it # TODO
  2742.     # If user is asleep, prefer moves that are usable while asleep
  2743.     if attacker.status==PBStatuses::SLEEP
  2744.       if skill>=PBTrainerAI.mediumSkill
  2745.         if move.function!=0x11 && move.function!=0xB4 # Snore, Sleep Talk
  2746.           hasSleepMove=false
  2747.           for m in attacker.moves
  2748.             if m.function==0x11 || m.function==0xB4 # Snore, Sleep Talk
  2749.               hasSleepMove=true; break
  2750.             end
  2751.           end
  2752.           score-=60 if hasSleepMove
  2753.         end
  2754.       end
  2755.     end
  2756.     # If user is frozen, prefer a move that can thaw the user
  2757.     if attacker.status==PBStatuses::FROZEN
  2758.       if skill>=PBTrainerAI.mediumSkill
  2759.         if move.canThawUser?
  2760.           score+=40
  2761.         else
  2762.           hasFreezeMove=false
  2763.           for m in attacker.moves
  2764.             if m.canThawUser?
  2765.               hasFreezeMove=true; break
  2766.             end
  2767.           end
  2768.           score-=60 if hasFreezeMove
  2769.         end
  2770.       end
  2771.     end
  2772.     # If target is frozen, don't prefer moves that could thaw them # TODO
  2773.     # Adjust score based on how much damage it can deal
  2774.     if move.basedamage>0
  2775.       typemod=pbTypeModifier(move.type,attacker,opponent)
  2776.       if typemod==0 || score<=0
  2777.         score=0
  2778.       elsif skill>=PBTrainerAI.mediumSkill && typemod<=8 &&
  2779.             opponent.hasWorkingAbility(:WONDERGUARD)
  2780.         score=0
  2781.       elsif skill>=PBTrainerAI.mediumSkill && isConst?(move.type,PBTypes,:GROUND) &&
  2782.             (opponent.hasWorkingAbility(:LEVITATE) ||
  2783.             opponent.effects[PBEffects::MagnetRise]>0)
  2784.         score=0
  2785.       elsif skill>=PBTrainerAI.mediumSkill && isConst?(move.type,PBTypes,:FIRE) &&
  2786.             opponent.hasWorkingAbility(:FLASHFIRE)
  2787.         score=0
  2788.       elsif skill>=PBTrainerAI.mediumSkill && isConst?(move.type,PBTypes,:WATER) &&
  2789.             (opponent.hasWorkingAbility(:WATERABSORB) ||
  2790.             opponent.hasWorkingAbility(:STORMDRAIN) ||
  2791.             opponent.hasWorkingAbility(:DRYSKIN))
  2792.         score=0
  2793.       elsif skill>=PBTrainerAI.mediumSkill && isConst?(move.type,PBTypes,:GRASS) &&
  2794.             opponent.hasWorkingAbility(:SAPSIPPER)
  2795.         score=0
  2796.       elsif skill>=PBTrainerAI.mediumSkill && isConst?(move.type,PBTypes,:ELECTRIC) &&
  2797.             (opponent.hasWorkingAbility(:VOLTABSORB) ||
  2798.             opponent.hasWorkingAbility(:LIGHTNINGROD) ||
  2799.             opponent.hasWorkingAbility(:MOTORDRIVE))
  2800.         score=0
  2801.       else
  2802.         # Calculate how much damage the move will do (roughly)
  2803.         realDamage=move.basedamage
  2804.         realDamage=60 if move.basedamage==1
  2805.         if skill>=PBTrainerAI.mediumSkill
  2806.           realDamage=pbBetterBaseDamage(move,attacker,opponent,skill,realDamage)
  2807.         end
  2808.         realDamage=pbRoughDamage(move,attacker,opponent,skill,realDamage)
  2809.         # Account for accuracy of move
  2810.         accuracy=pbRoughAccuracy(move,attacker,opponent,skill)
  2811.         basedamage=realDamage*accuracy/100.0
  2812.         # Two-turn attacks waste 2 turns to deal one lot of damage
  2813.         if move.pbTwoTurnAttack(attacker) || move.function==0xC2 # Hyper Beam
  2814.           basedamage*=2/3   # Not halved because semi-invulnerable during use or hits first turn
  2815.         end
  2816.         # Prefer flinching effects
  2817.         if !opponent.hasWorkingAbility(:INNERFOCUS) &&
  2818.            opponent.effects[PBEffects::Substitute]==0
  2819.           if (attacker.hasWorkingItem(:KINGSROCK) || attacker.hasWorkingItem(:RAZORFANG)) &&
  2820.              move.canKingsRock?
  2821.             basedamage*=1.05
  2822.           elsif attacker.hasWorkingAbility(:STENCH) &&
  2823.                 move.function!=0x09 && # Thunder Fang
  2824.                 move.function!=0x0B && # Fire Fang
  2825.                 move.function!=0x0E && # Ice Fang
  2826.                 move.function!=0x0F && # flinch-inducing moves
  2827.                 move.function!=0x10 && # Stomp
  2828.                 move.function!=0x11 && # Snore
  2829.                 move.function!=0x12 && # Fake Out
  2830.                 move.function!=0x78 && # Twister
  2831.                 move.function!=0xC7    # Sky Attack
  2832.             basedamage*=1.05
  2833.           end
  2834.         end
  2835.         # Convert damage to proportion of opponent's remaining HP
  2836.         basedamage=(basedamage*100.0/opponent.hp)
  2837.         # Don't prefer weak attacks
  2838. #        basedamage/=2 if basedamage<40
  2839.         # Prefer damaging attack if level difference is significantly high
  2840.         basedamage*=1.2 if attacker.level-10>opponent.level
  2841.         # Adjust score
  2842.         basedamage=basedamage.round
  2843.         basedamage=120 if basedamage>120   # Treat all OHKO moves the same
  2844.         basedamage+=40 if basedamage>100   # Prefer moves likely to OHKO
  2845.         score=score.round
  2846.         oldscore=score
  2847.         score+=basedamage
  2848.         PBDebug.log("[AI] #{PBMoves.getName(move.id)} damage calculated (#{realDamage}=>#{basedamage}% of target's #{opponent.hp} HP), score change #{oldscore}=>#{score}")
  2849.       end
  2850.     else
  2851.       # Don't prefer attacks which don't deal damage
  2852.       score-=10
  2853.       # Account for accuracy of move
  2854.       accuracy=pbRoughAccuracy(move,attacker,opponent,skill)
  2855.       score*=accuracy/100.0
  2856.       score=0 if score<=10 && skill>=PBTrainerAI.highSkill
  2857.     end
  2858.     score=score.to_i
  2859.     score=0 if score<0
  2860.     return score
  2861.   end
  2862.  
  2863. ################################################################################
  2864. # Get type effectiveness and approximate stats.
  2865. ################################################################################
  2866.   def pbTypeModifier(type,attacker,opponent)
  2867.     return 8 if type<0
  2868.     return 8 if isConst?(type,PBTypes,:GROUND) && opponent.pbHasType?(:FLYING) &&
  2869.                 opponent.hasWorkingItem(:IRONBALL) && !USENEWBATTLEMECHANICS
  2870.     atype=type
  2871.     otype1=opponent.type1
  2872.     otype2=opponent.type2
  2873.     otype3=opponent.effects[PBEffects::Type3] || -1
  2874.     # Roost
  2875.     if isConst?(otype1,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  2876.       if isConst?(otype2,PBTypes,:FLYING) && isConst?(otype3,PBTypes,:FLYING)
  2877.         otype1=getConst(PBTypes,:NORMAL) || 0
  2878.       else
  2879.         otype1=otype2
  2880.       end
  2881.     end
  2882.     if isConst?(otype2,PBTypes,:FLYING) && opponent.effects[PBEffects::Roost]
  2883.       otype2=otype1
  2884.     end
  2885.     # Get effectivenesses
  2886.     mod1=PBTypes.getEffectiveness(atype,otype1)
  2887.     mod2=(otype1==otype2) ? 2 : PBTypes.getEffectiveness(atype,otype2)
  2888.     mod3=(otype3<0 || otype1==otype3 || otype2==otype3) ? 2 : PBTypes.getEffectiveness(atype,otype3)
  2889.     if opponent.hasWorkingItem(:RINGTARGET)
  2890.       mod1=2 if mod1==0
  2891.       mod2=2 if mod2==0
  2892.       mod3=2 if mod3==0
  2893.     end
  2894.     # Foresight
  2895.     if (attacker.hasWorkingAbility(:SCRAPPY) rescue false) || opponent.effects[PBEffects::Foresight]
  2896.       mod1=2 if isConst?(otype1,PBTypes,:GHOST) && PBTypes.isIneffective?(atype,otype1)
  2897.       mod2=2 if isConst?(otype2,PBTypes,:GHOST) && PBTypes.isIneffective?(atype,otype2)
  2898.       mod3=2 if isConst?(otype3,PBTypes,:GHOST) && PBTypes.isIneffective?(atype,otype3)
  2899.     end
  2900.     # Miracle Eye
  2901.     if opponent.effects[PBEffects::MiracleEye]
  2902.       mod1=2 if isConst?(otype1,PBTypes,:DARK) && PBTypes.isIneffective?(atype,otype1)
  2903.       mod2=2 if isConst?(otype2,PBTypes,:DARK) && PBTypes.isIneffective?(atype,otype2)
  2904.       mod3=2 if isConst?(otype3,PBTypes,:DARK) && PBTypes.isIneffective?(atype,otype3)
  2905.     end
  2906.     # Delta Stream's weather
  2907.     if pbWeather==PBWeather::STRONGWINDS
  2908.       mod1=2 if isConst?(otype1,PBTypes,:FLYING) && PBTypes.isSuperEffective?(atype,otype1)
  2909.       mod2=2 if isConst?(otype2,PBTypes,:FLYING) && PBTypes.isSuperEffective?(atype,otype2)
  2910.       mod3=2 if isConst?(otype3,PBTypes,:FLYING) && PBTypes.isSuperEffective?(atype,otype3)
  2911.     end
  2912.     # Smack Down makes Ground moves work against fliers
  2913.     if !opponent.isAirborne?((attacker.hasMoldBreaker rescue false)) && isConst?(atype,PBTypes,:GROUND)
  2914.       mod1=2 if isConst?(otype1,PBTypes,:FLYING)
  2915.       mod2=2 if isConst?(otype2,PBTypes,:FLYING)
  2916.       mod3=2 if isConst?(otype3,PBTypes,:FLYING)
  2917.     end
  2918.     return mod1*mod2*mod3
  2919.   end
  2920.  
  2921.   def pbTypeModifier2(battlerThis,battlerOther)
  2922.     # battlerThis isn't a Battler object, it's a Pokémon - it has no third type
  2923.     if battlerThis.type1==battlerThis.type2
  2924.       return 4*pbTypeModifier(battlerThis.type1,battlerThis,battlerOther)
  2925.     end
  2926.     ret=pbTypeModifier(battlerThis.type1,battlerThis,battlerOther)
  2927.     ret*=pbTypeModifier(battlerThis.type2,battlerThis,battlerOther)
  2928.     return ret*2 # 0,1,2,4,_8_,16,32,64
  2929.   end
  2930.  
  2931.   def pbRoughStat(battler,stat,skill)
  2932.     return battler.pbSpeed if skill>=PBTrainerAI.highSkill && stat==PBStats::SPEED
  2933.     stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40]
  2934.     stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10]
  2935.     stage=battler.stages[stat]+6
  2936.     value=0
  2937.     case stat
  2938.     when PBStats::ATTACK; value=battler.attack
  2939.     when PBStats::DEFENSE; value=battler.defense
  2940.     when PBStats::SPEED; value=battler.speed
  2941.     when PBStats::SPATK; value=battler.spatk
  2942.     when PBStats::SPDEF; value=battler.spdef
  2943.     end
  2944.     return (value*1.0*stagemul[stage]/stagediv[stage]).floor
  2945.   end
  2946.  
  2947.   def pbBetterBaseDamage(move,attacker,opponent,skill,basedamage)
  2948.     # Covers all function codes which have their own def pbBaseDamage
  2949.     case move.function
  2950.     when 0x6A # SonicBoom
  2951.       basedamage=20
  2952.     when 0x6B # Dragon Rage
  2953.       basedamage=40
  2954.     when 0x6C # Super Fang
  2955.       basedamage=(opponent.hp/2).floor
  2956.     when 0x6D # Night Shade
  2957.       basedamage=attacker.level
  2958.     when 0x6E # Endeavor
  2959.       basedamage=opponent.hp-attacker.hp
  2960.     when 0x6F # Psywave
  2961.       basedamage=attacker.level
  2962.     when 0x70 # OHKO
  2963.       basedamage=opponent.totalhp
  2964.     when 0x71 # Counter
  2965.       basedamage=60
  2966.     when 0x72 # Mirror Coat
  2967.       basedamage=60
  2968.     when 0x73 # Metal Burst
  2969.       basedamage=60
  2970.     when 0x75, 0x12D # Surf, Shadow Storm
  2971.       basedamage*=2 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCB # Dive
  2972.     when 0x76 # Earthquake
  2973.       basedamage*=2 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCA # Dig
  2974.     when 0x77, 0x78 # Gust, Twister
  2975.       basedamage*=2 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xC9 || # Fly
  2976.                        PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCC || # Bounce
  2977.                        PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCE    # Sky Drop
  2978.     when 0x7B # Venoshock
  2979.       basedamage*=2 if opponent.status==PBStatuses::POISON
  2980.     when 0x7C # SmellingSalt
  2981.       basedamage*=2 if opponent.status==PBStatuses::PARALYSIS
  2982.     when 0x7D # Wake-Up Slap
  2983.       basedamage*=2 if opponent.status==PBStatuses::SLEEP
  2984.     when 0x7E # Facade
  2985.       basedamage*=2 if attacker.status==PBStatuses::POISON ||
  2986.                        attacker.status==PBStatuses::BURN ||
  2987.                        attacker.status==PBStatuses::PARALYSIS
  2988.     when 0x7F # Hex
  2989.       basedamage*=2 if opponent.status!=0
  2990.     when 0x80 # Brine
  2991.       basedamage*=2 if opponent.hp<=(opponent.totalhp/2).floor
  2992.     when 0x85 # Retaliate
  2993.       # TODO
  2994.     when 0x86 # Acrobatics
  2995.       basedamage*=2 if attacker.item==0 || attacker.hasWorkingItem(:FLYINGGEM)
  2996.     when 0x87 # Weather Ball
  2997.       basedamage*=2 if pbWeather!=0
  2998.     when 0x89 # Return
  2999.       basedamage=[(attacker.happiness*2/5).floor,1].max
  3000.     when 0x8A # Frustration
  3001.       basedamage=[((255-attacker.happiness)*2/5).floor,1].max
  3002.     when 0x8B # Eruption
  3003.       basedamage=[(150*attacker.hp/attacker.totalhp).floor,1].max
  3004.     when 0x8C # Crush Grip
  3005.       basedamage=[(120*opponent.hp/opponent.totalhp).floor,1].max
  3006.     when 0x8D # Gyro Ball
  3007.       ospeed=pbRoughStat(opponent,PBStats::SPEED,skill)
  3008.       aspeed=pbRoughStat(attacker,PBStats::SPEED,skill)
  3009.       basedamage=[[(25*ospeed/aspeed).floor,150].min,1].max
  3010.     when 0x8E # Stored Power
  3011.       mult=0
  3012.       for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  3013.                 PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  3014.         mult+=attacker.stages[i] if attacker.stages[i]>0
  3015.       end
  3016.       basedamage=20*(mult+1)
  3017.     when 0x8F # Punishment
  3018.       mult=0
  3019.       for i in [PBStats::ATTACK,PBStats::DEFENSE,PBStats::SPEED,
  3020.                 PBStats::SPATK,PBStats::SPDEF,PBStats::ACCURACY,PBStats::EVASION]
  3021.         mult+=opponent.stages[i] if opponent.stages[i]>0
  3022.       end
  3023.       basedamage=[20*(mult+3),200].min
  3024.     when 0x90 # Hidden Power
  3025.       hp=pbHiddenPower(attacker.iv)
  3026.       basedamage=hp[1]
  3027.     when 0x91 # Fury Cutter
  3028.       basedamage=basedamage<<(attacker.effects[PBEffects::FuryCutter]-1)
  3029.     when 0x92 # Echoed Voice
  3030.       basedamage*=attacker.pbOwnSide.effects[PBEffects::EchoedVoiceCounter]
  3031.     when 0x94 # Present
  3032.       basedamage=50
  3033.     when 0x95 # Magnitude
  3034.       basedamage=71
  3035.       basedamage*=2 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCA # Dig
  3036.     when 0x96 # Natural Gift
  3037.       damagearray={
  3038.          60 => [:CHERIBERRY,:CHESTOBERRY,:PECHABERRY,:RAWSTBERRY,:ASPEARBERRY,
  3039.                 :LEPPABERRY,:ORANBERRY,:PERSIMBERRY,:LUMBERRY,:SITRUSBERRY,
  3040.                 :FIGYBERRY,:WIKIBERRY,:MAGOBERRY,:AGUAVBERRY,:IAPAPABERRY,
  3041.                 :RAZZBERRY,:OCCABERRY,:PASSHOBERRY,:WACANBERRY,:RINDOBERRY,
  3042.                 :YACHEBERRY,:CHOPLEBERRY,:KEBIABERRY,:SHUCABERRY,:COBABERRY,
  3043.                 :PAYAPABERRY,:TANGABERRY,:CHARTIBERRY,:KASIBBERRY,:HABANBERRY,
  3044.                 :COLBURBERRY,:BABIRIBERRY,:CHILANBERRY],
  3045.          70 => [:BLUKBERRY,:NANABBERRY,:WEPEARBERRY,:PINAPBERRY,:POMEGBERRY,
  3046.                 :KELPSYBERRY,:QUALOTBERRY,:HONDEWBERRY,:GREPABERRY,:TAMATOBERRY,
  3047.                 :CORNNBERRY,:MAGOSTBERRY,:RABUTABERRY,:NOMELBERRY,:SPELONBERRY,
  3048.                 :PAMTREBERRY],
  3049.          80 => [:WATMELBERRY,:DURINBERRY,:BELUEBERRY,:LIECHIBERRY,:GANLONBERRY,
  3050.                 :SALACBERRY,:PETAYABERRY,:APICOTBERRY,:LANSATBERRY,:STARFBERRY,
  3051.                 :ENIGMABERRY,:MICLEBERRY,:CUSTAPBERRY,:JABOCABERRY,:ROWAPBERRY]
  3052.       }
  3053.       haveanswer=false
  3054.       for i in damagearray.keys
  3055.         data=damagearray[i]
  3056.         if data
  3057.           for j in data
  3058.             if isConst?(attacker.item,PBItems,j)
  3059.               basedamage=i; haveanswer=true; break
  3060.             end
  3061.           end
  3062.         end
  3063.         break if haveanswer
  3064.       end
  3065.     when 0x97 # Trump Card
  3066.       dmgs=[200,80,60,50,40]
  3067.       ppleft=[move.pp-1,4].min   # PP is reduced before the move is used
  3068.       basedamage=dmgs[ppleft]
  3069.     when 0x98 # Flail
  3070.       n=(48*attacker.hp/attacker.totalhp).floor
  3071.       basedamage=20
  3072.       basedamage=40 if n<33
  3073.       basedamage=80 if n<17
  3074.       basedamage=100 if n<10
  3075.       basedamage=150 if n<5
  3076.       basedamage=200 if n<2
  3077.     when 0x99 # Electro Ball
  3078.       n=(attacker.pbSpeed/opponent.pbSpeed).floor
  3079.       basedamage=40
  3080.       basedamage=60 if n>=1
  3081.       basedamage=80 if n>=2
  3082.       basedamage=120 if n>=3
  3083.       basedamage=150 if n>=4
  3084.     when 0x9A # Low Kick
  3085.       weight=opponent.weight
  3086.       basedamage=20
  3087.       basedamage=40 if weight>100
  3088.       basedamage=60 if weight>250
  3089.       basedamage=80 if weight>500
  3090.       basedamage=100 if weight>1000
  3091.       basedamage=120 if weight>2000
  3092.     when 0x9B # Heavy Slam
  3093.       n=(attacker.weight/opponent.weight).floor
  3094.       basedamage=40
  3095.       basedamage=60 if n>=2
  3096.       basedamage=80 if n>=3
  3097.       basedamage=100 if n>=4
  3098.       basedamage=120 if n>=5
  3099.     when 0xA0 # Frost Breath
  3100.       basedamage*=2
  3101.     when 0xBD, 0xBE # Double Kick, Twineedle
  3102.       basedamage*=2
  3103.     when 0xBF # Triple Kick
  3104.       basedamage*=6
  3105.     when 0xC0 # Fury Attack
  3106.       if attacker.hasWorkingAbility(:SKILLLINK)
  3107.         basedamage*=5
  3108.       else
  3109.         basedamage=(basedamage*19/6).floor
  3110.       end
  3111.     when 0xC1 # Beat Up
  3112.       party=pbParty(attacker.index)
  3113.       mult=0
  3114.       for i in 0...party.length
  3115.         mult+=1 if party[i] && !party[i].egg? &&
  3116.                    party[i].hp>0 && party[i].status==0
  3117.       end
  3118.       basedamage*=mult
  3119.     when 0xC4 # SolarBeam
  3120.       if pbWeather!=0 && pbWeather!=PBWeather::SUNNYDAY
  3121.         basedamage=(basedamage*0.5).floor
  3122.       end
  3123.     when 0xD0 # Whirlpool
  3124.       if skill>=PBTrainerAI.mediumSkill
  3125.         basedamage*=2 if PBMoveData.new(opponent.effects[PBEffects::TwoTurnAttack]).function==0xCB # Dive
  3126.       end
  3127.     when 0xD3 # Rollout
  3128.       if skill>=PBTrainerAI.mediumSkill
  3129.         basedamage*=2 if attacker.effects[PBEffects::DefenseCurl]
  3130.       end
  3131.     when 0xE1 # Final Gambit
  3132.       basedamage=attacker.hp
  3133.     when 0xF7 # Fling
  3134.       # TODO
  3135.     when 0x113 # Spit Up
  3136.       basedamage*=attacker.effects[PBEffects::Stockpile]
  3137.     when 0x144
  3138.       type=getConst(PBTypes,:FLYING) || -1
  3139.       if type>=0
  3140.         mult=PBTypes.getCombinedEffectiveness(type,
  3141.            opponent.type1,opponent.type2,opponent.effects[PBEffects::Type3])
  3142.         basedamage=((basedamage*mult)/8).round
  3143.       end
  3144.     end
  3145.     return basedamage
  3146.   end
  3147.  
  3148.   def pbRoughDamage(move,attacker,opponent,skill,basedamage)
  3149.     # Fixed damage moves
  3150.     return basedamage if move.function==0x6A ||   # SonicBoom
  3151.                          move.function==0x6B ||   # Dragon Rage
  3152.                          move.function==0x6C ||   # Super Fang
  3153.                          move.function==0x6D ||   # Night Shade
  3154.                          move.function==0x6E ||   # Endeavor
  3155.                          move.function==0x6F ||   # Psywave
  3156.                          move.function==0x70 ||   # OHKO
  3157.                          move.function==0x71 ||   # Counter
  3158.                          move.function==0x72 ||   # Mirror Coat
  3159.                          move.function==0x73 ||   # Metal Burst
  3160.                          move.function==0xE1      # Final Gambit
  3161.     type=move.type
  3162.     # More accurate move type (includes Normalize, most type-changing moves, etc.)
  3163.     if skill>=PBTrainerAI.highSkill
  3164.       type=move.pbType(type,attacker,opponent)
  3165.     end
  3166.     # Technician
  3167.     if skill>=PBTrainerAI.highSkill
  3168.       if attacker.hasWorkingAbility(:TECHNICIAN) && basedamage<=60
  3169.         basedamage=(basedamage*1.5).round
  3170.       end
  3171.     end
  3172.     # Iron Fist
  3173.     if skill>=PBTrainerAI.mediumSkill
  3174.       if attacker.hasWorkingAbility(:IRONFIST) && move.isPunchingMove?
  3175.         basedamage=(basedamage*1.2).round
  3176.       end
  3177.     end
  3178.     # Reckless
  3179.     if skill>=PBTrainerAI.mediumSkill
  3180.       if attacker.hasWorkingAbility(:RECKLESS)
  3181.         if @function==0xFA ||  # Take Down, etc.
  3182.            @function==0xFB ||  # Double-Edge, etc.
  3183.            @function==0xFC ||  # Head Smash
  3184.            @function==0xFD ||  # Volt Tackle
  3185.            @function==0xFE ||  # Flare Blitz
  3186.            @function==0x10B || # Jump Kick, Hi Jump Kick
  3187.            @function==0x130    # Shadow End
  3188.           basedamage=(basedamage*1.2).round
  3189.         end
  3190.       end
  3191.     end
  3192.     # Flare Boost
  3193.     if skill>=PBTrainerAI.highSkill
  3194.       if attacker.hasWorkingAbility(:FLAREBOOST) &&
  3195.          attacker.status==PBStatuses::BURN && move.pbIsSpecial?(type)
  3196.         basedamage=(basedamage*1.5).round
  3197.       end
  3198.     end
  3199.     # Toxic Boost
  3200.     if skill>=PBTrainerAI.highSkill
  3201.       if attacker.hasWorkingAbility(:TOXICBOOST) &&
  3202.          attacker.status==PBStatuses::POISON && move.pbIsPhysical?(type)
  3203.         basedamage=(basedamage*1.5).round
  3204.       end
  3205.     end
  3206.     # Analytic
  3207.     # Rivalry
  3208.     if skill>=PBTrainerAI.mediumSkill
  3209.       if attacker.hasWorkingAbility(:RIVALRY) &&
  3210.          attacker.gender!=2 && opponent.gender!=2
  3211.         if attacker.gender==opponent.gender
  3212.           basedamage=(basedamage*1.25).round
  3213.         else
  3214.           basedamage=(basedamage*0.75).round
  3215.         end
  3216.       end
  3217.     end
  3218.     # Sand Force
  3219.     if skill>=PBTrainerAI.mediumSkill
  3220.       if attacker.hasWorkingAbility(:SANDFORCE) &&
  3221.          pbWeather==PBWeather::SANDSTORM &&
  3222.          (isConst?(type,PBTypes,:ROCK) ||
  3223.          isConst?(type,PBTypes,:GROUND) ||
  3224.          isConst?(type,PBTypes,:STEEL))
  3225.         basedamage=(basedamage*1.3).round
  3226.       end
  3227.     end
  3228.     # Heatproof
  3229.     if skill>=PBTrainerAI.bestSkill
  3230.       if opponent.hasWorkingAbility(:HEATPROOF) &&
  3231.          isConst?(type,PBTypes,:FIRE)
  3232.         basedamage=(basedamage*0.5).round
  3233.       end
  3234.     end
  3235.     # Dry Skin
  3236.     if skill>=PBTrainerAI.bestSkill
  3237.       if opponent.hasWorkingAbility(:DRYSKIN) &&
  3238.          isConst?(type,PBTypes,:FIRE)
  3239.         basedamage=(basedamage*1.25).round
  3240.       end
  3241.     end
  3242.     # Sheer Force
  3243.     if skill>=PBTrainerAI.highSkill
  3244.       if attacker.hasWorkingAbility(:SHEERFORCE) && move.addlEffect>0
  3245.         basedamage=(basedamage*1.3).round
  3246.       end
  3247.     end
  3248.     # Type-boosting items
  3249.     if (attacker.hasWorkingItem(:SILKSCARF) && isConst?(type,PBTypes,:NORMAL)) ||
  3250.        (attacker.hasWorkingItem(:BLACKBELT) && isConst?(type,PBTypes,:FIGHTING)) ||
  3251.        (attacker.hasWorkingItem(:SHARPBEAK) && isConst?(type,PBTypes,:FLYING)) ||
  3252.        (attacker.hasWorkingItem(:POISONBARB) && isConst?(type,PBTypes,:POISON)) ||
  3253.        (attacker.hasWorkingItem(:SOFTSAND) && isConst?(type,PBTypes,:GROUND)) ||
  3254.        (attacker.hasWorkingItem(:HARDSTONE) && isConst?(type,PBTypes,:ROCK)) ||
  3255.        (attacker.hasWorkingItem(:SILVERPOWDER) && isConst?(type,PBTypes,:BUG)) ||
  3256.        (attacker.hasWorkingItem(:SPELLTAG) && isConst?(type,PBTypes,:GHOST)) ||
  3257.        (attacker.hasWorkingItem(:METALCOAT) && isConst?(type,PBTypes,:STEEL)) ||
  3258.        (attacker.hasWorkingItem(:CHARCOAL) && isConst?(type,PBTypes,:FIRE)) ||
  3259.        (attacker.hasWorkingItem(:MYSTICWATER) && isConst?(type,PBTypes,:WATER)) ||
  3260.        (attacker.hasWorkingItem(:MIRACLESEED) && isConst?(type,PBTypes,:GRASS)) ||
  3261.        (attacker.hasWorkingItem(:MAGNET) && isConst?(type,PBTypes,:ELECTRIC)) ||
  3262.        (attacker.hasWorkingItem(:TWISTEDSPOON) && isConst?(type,PBTypes,:PSYCHIC)) ||
  3263.        (attacker.hasWorkingItem(:NEVERMELTICE) && isConst?(type,PBTypes,:ICE)) ||
  3264.        (attacker.hasWorkingItem(:DRAGONFANG) && isConst?(type,PBTypes,:DRAGON)) ||
  3265.        (attacker.hasWorkingItem(:BLACKGLASSES) && isConst?(type,PBTypes,:DARK))
  3266.       basedamage=(basedamage*1.2).round
  3267.     end
  3268.     if (attacker.hasWorkingItem(:FISTPLATE) && isConst?(type,PBTypes,:FIGHTING)) ||
  3269.        (attacker.hasWorkingItem(:SKYPLATE) && isConst?(type,PBTypes,:FLYING)) ||
  3270.        (attacker.hasWorkingItem(:TOXICPLATE) && isConst?(type,PBTypes,:POISON)) ||
  3271.        (attacker.hasWorkingItem(:EARTHPLATE) && isConst?(type,PBTypes,:GROUND)) ||
  3272.        (attacker.hasWorkingItem(:STONEPLATE) && isConst?(type,PBTypes,:ROCK)) ||
  3273.        (attacker.hasWorkingItem(:INSECTPLATE) && isConst?(type,PBTypes,:BUG)) ||
  3274.        (attacker.hasWorkingItem(:SPOOKYPLATE) && isConst?(type,PBTypes,:GHOST)) ||
  3275.        (attacker.hasWorkingItem(:IRONPLATE) && isConst?(type,PBTypes,:STEEL)) ||
  3276.        (attacker.hasWorkingItem(:FLAMEPLATE) && isConst?(type,PBTypes,:FIRE)) ||
  3277.        (attacker.hasWorkingItem(:SPLASHPLATE) && isConst?(type,PBTypes,:WATER)) ||
  3278.        (attacker.hasWorkingItem(:MEADOWPLATE) && isConst?(type,PBTypes,:GRASS)) ||
  3279.        (attacker.hasWorkingItem(:ZAPPLATE) && isConst?(type,PBTypes,:ELECTRIC)) ||
  3280.        (attacker.hasWorkingItem(:MINDPLATE) && isConst?(type,PBTypes,:PSYCHIC)) ||
  3281.        (attacker.hasWorkingItem(:ICICLEPLATE) && isConst?(type,PBTypes,:ICE)) ||
  3282.        (attacker.hasWorkingItem(:DRACOPLATE) && isConst?(type,PBTypes,:DRAGON)) ||
  3283.        (attacker.hasWorkingItem(:DREADPLATE) && isConst?(type,PBTypes,:DARK)) ||
  3284.        (attacker.hasWorkingItem(:PIXIEPLATE) && isConst?(type,PBTypes,:FAIRY))
  3285.       basedamage=(basedamage*1.2).round
  3286.     end
  3287.     if (attacker.hasWorkingItem(:NORMALGEM) && isConst?(type,PBTypes,:NORMAL)) ||
  3288.        (attacker.hasWorkingItem(:FIGHTINGGEM) && isConst?(type,PBTypes,:FIGHTING)) ||
  3289.        (attacker.hasWorkingItem(:FLYINGGEM) && isConst?(type,PBTypes,:FLYING)) ||
  3290.        (attacker.hasWorkingItem(:POISONGEM) && isConst?(type,PBTypes,:POISON)) ||
  3291.        (attacker.hasWorkingItem(:GROUNDGEM) && isConst?(type,PBTypes,:GROUND)) ||
  3292.        (attacker.hasWorkingItem(:ROCKGEM) && isConst?(type,PBTypes,:ROCK)) ||
  3293.        (attacker.hasWorkingItem(:BUGGEM) && isConst?(type,PBTypes,:BUG)) ||
  3294.        (attacker.hasWorkingItem(:GHOSTGEM) && isConst?(type,PBTypes,:GHOST)) ||
  3295.        (attacker.hasWorkingItem(:STEELGEM) && isConst?(type,PBTypes,:STEEL)) ||
  3296.        (attacker.hasWorkingItem(:FIREGEM) && isConst?(type,PBTypes,:FIRE)) ||
  3297.        (attacker.hasWorkingItem(:WATERGEM) && isConst?(type,PBTypes,:WATER)) ||
  3298.        (attacker.hasWorkingItem(:GRASSGEM) && isConst?(type,PBTypes,:GRASS)) ||
  3299.        (attacker.hasWorkingItem(:ELECTRICGEM) && isConst?(type,PBTypes,:ELECTRIC)) ||
  3300.        (attacker.hasWorkingItem(:PSYCHICGEM) && isConst?(type,PBTypes,:PSYCHIC)) ||
  3301.        (attacker.hasWorkingItem(:ICEGEM) && isConst?(type,PBTypes,:ICE)) ||
  3302.        (attacker.hasWorkingItem(:DRAGONGEM) && isConst?(type,PBTypes,:DRAGON)) ||
  3303.        (attacker.hasWorkingItem(:DARKGEM) && isConst?(type,PBTypes,:DARK)) ||
  3304.        (attacker.hasWorkingItem(:FAIRYGEM) && isConst?(type,PBTypes,:FAIRY))
  3305.       basedamage=(basedamage*1.5).round
  3306.     end
  3307.     if attacker.hasWorkingItem(:ROCKINCENSE) && isConst?(type,PBTypes,:ROCK)
  3308.       basedamage=(basedamage*1.2).round
  3309.     end
  3310.     if attacker.hasWorkingItem(:ROSEINCENSE) && isConst?(type,PBTypes,:GRASS)
  3311.       basedamage=(basedamage*1.2).round
  3312.     end
  3313.     if attacker.hasWorkingItem(:SEAINCENSE) && isConst?(type,PBTypes,:WATER)
  3314.       basedamage=(basedamage*1.2).round
  3315.     end
  3316.     if attacker.hasWorkingItem(:WAVEINCENSE) && isConst?(type,PBTypes,:WATER)
  3317.       basedamage=(basedamage*1.2).round
  3318.     end
  3319.     if attacker.hasWorkingItem(:ODDINCENSE) && isConst?(type,PBTypes,:PSYCHIC)
  3320.       basedamage=(basedamage*1.2).round
  3321.     end
  3322.     # Muscle Band
  3323.     if attacker.hasWorkingItem(:MUSCLEBAND) && move.pbIsPhysical?(type)
  3324.       basedamage=(basedamage*1.1).round
  3325.     end
  3326.     # Wise Glasses
  3327.     if attacker.hasWorkingItem(:WISEGLASSES) && move.pbIsSpecial?(type)
  3328.       basedamage=(basedamage*1.1).round
  3329.     end
  3330.     # Legendary Orbs
  3331.     if isConst?(attacker.species,PBSpecies,:PALKIA) &&
  3332.        attacker.hasWorkingItem(:LUSTROUSORB) &&
  3333.        (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:WATER))
  3334.       basedamage=(basedamage*1.2).round
  3335.     end
  3336.     if isConst?(attacker.species,PBSpecies,:DIALGA) &&
  3337.        attacker.hasWorkingItem(:ADAMANTORB) &&
  3338.        (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:STEEL))
  3339.       basedamage=(basedamage*1.2).round
  3340.     end
  3341.     if isConst?(attacker.species,PBSpecies,:GIRATINA) &&
  3342.        attacker.hasWorkingItem(:GRISEOUSORB) &&
  3343.        (isConst?(type,PBTypes,:DRAGON) || isConst?(type,PBTypes,:GHOST))
  3344.       basedamage=(basedamage*1.2).round
  3345.     end
  3346.     # pbBaseDamageMultiplier - TODO
  3347.     # Me First
  3348.     # Charge
  3349.     if attacker.effects[PBEffects::Charge]>0 && isConst?(type,PBTypes,:ELECTRIC)
  3350.       basedamage=(basedamage*2.0).round
  3351.     end
  3352.     # Helping Hand - n/a
  3353.     # Water Sport
  3354.     if skill>=PBTrainerAI.mediumSkill
  3355.       if isConst?(type,PBTypes,:FIRE)
  3356.         for i in 0...4
  3357.           if @battlers[i].effects[PBEffects::WaterSport] && !@battlers[i].fainted?
  3358.             basedamage=(basedamage*0.33).round
  3359.             break
  3360.           end
  3361.         end
  3362.       end
  3363.     end
  3364.     # Mud Sport
  3365.     if skill>=PBTrainerAI.mediumSkill
  3366.       if isConst?(type,PBTypes,:ELECTRIC)
  3367.         for i in 0...4
  3368.           if @battlers[i].effects[PBEffects::MudSport] && !@battlers[i].fainted?
  3369.             basedamage=(basedamage*0.33).round
  3370.             break
  3371.           end
  3372.         end
  3373.       end
  3374.     end
  3375.     # Get base attack stat
  3376.     atk=pbRoughStat(attacker,PBStats::ATTACK,skill)
  3377.     if move.function==0x121 # Foul Play
  3378.       atk=pbRoughStat(opponent,PBStats::ATTACK,skill)
  3379.     end
  3380.     if type>=0 && move.pbIsSpecial?(type)
  3381.       atk=pbRoughStat(attacker,PBStats::SPATK,skill)
  3382.       if move.function==0x121 # Foul Play
  3383.         atk=pbRoughStat(opponent,PBStats::SPATK,skill)
  3384.       end
  3385.     end
  3386.     # Hustle
  3387.     if skill>=PBTrainerAI.highSkill
  3388.       if attacker.hasWorkingAbility(:HUSTLE) && move.pbIsPhysical?(type)
  3389.         atk=(atk*1.5).round
  3390.       end
  3391.     end
  3392.     # Thick Fat
  3393.     if skill>=PBTrainerAI.bestSkill
  3394.       if opponent.hasWorkingAbility(:THICKFAT) &&
  3395.          (isConst?(type,PBTypes,:ICE) || isConst?(type,PBTypes,:FIRE))
  3396.         atk=(atk*0.5).round
  3397.       end
  3398.     end
  3399.     # Pinch abilities
  3400.     if skill>=PBTrainerAI.mediumSkill
  3401.       if attacker.hp<=(attacker.totalhp/3).floor
  3402.         if (attacker.hasWorkingAbility(:OVERGROW) && isConst?(type,PBTypes,:GRASS)) ||
  3403.            (attacker.hasWorkingAbility(:BLAZE) && isConst?(type,PBTypes,:FIRE)) ||
  3404.            (attacker.hasWorkingAbility(:TORRENT) && isConst?(type,PBTypes,:WATER)) ||
  3405.            (attacker.hasWorkingAbility(:SWARM) && isConst?(type,PBTypes,:BUG))
  3406.           atk=(atk*1.5).round
  3407.         end
  3408.       end
  3409.     end
  3410.     # Guts
  3411.     if skill>=PBTrainerAI.highSkill
  3412.       if attacker.hasWorkingAbility(:GUTS) &&
  3413.          attacker.status!=0 && move.pbIsPhysical?(type)
  3414.         atk=(atk*1.5).round
  3415.       end
  3416.     end
  3417.     # Plus, Minus
  3418.     if skill>=PBTrainerAI.mediumSkill
  3419.       if (attacker.hasWorkingAbility(:PLUS) ||
  3420.          attacker.hasWorkingAbility(:MINUS)) && move.pbIsSpecial?(type)
  3421.         partner=attacker.pbPartner
  3422.         if partner.hasWorkingAbility(:PLUS) || partner.hasWorkingAbility(:MINUS)
  3423.           atk=(atk*1.5).round
  3424.         end
  3425.       end
  3426.     end
  3427.     # Defeatist
  3428.     if skill>=PBTrainerAI.mediumSkill
  3429.       if attacker.hasWorkingAbility(:DEFEATIST) &&
  3430.          attacker.hp<=(attacker.totalhp/2).floor
  3431.         atk=(atk*0.5).round
  3432.       end
  3433.     end
  3434.     # Pure Power, Huge Power
  3435.     if skill>=PBTrainerAI.mediumSkill
  3436.       if attacker.hasWorkingAbility(:PUREPOWER) ||
  3437.          attacker.hasWorkingAbility(:HUGEPOWER)
  3438.         atk=(atk*2.0).round
  3439.       end
  3440.     end
  3441.     # Solar Power
  3442.     if skill>=PBTrainerAI.highSkill
  3443.       if attacker.hasWorkingAbility(:SOLARPOWER) &&
  3444.          pbWeather==PBWeather::SUNNYDAY && move.pbIsSpecial?(type)
  3445.         atk=(atk*1.5).round
  3446.       end
  3447.     end
  3448.     # Flash Fire
  3449.     if skill>=PBTrainerAI.highSkill
  3450.       if attacker.hasWorkingAbility(:FLASHFIRE) &&
  3451.          attacker.effects[PBEffects::FlashFire] && isConst?(type,PBTypes,:FIRE)
  3452.         atk=(atk*1.5).round
  3453.       end
  3454.     end
  3455.     # Slow Start
  3456.     if skill>=PBTrainerAI.mediumSkill
  3457.       if attacker.hasWorkingAbility(:SLOWSTART) &&
  3458.          attacker.turncount<5 && move.pbIsPhysical?(type)
  3459.         atk=(atk*0.5).round
  3460.       end
  3461.     end
  3462.     # Flower Gift
  3463.     if skill>=PBTrainerAI.highSkill
  3464.       if pbWeather==PBWeather::SUNNYDAY && move.pbIsPhysical?(type)
  3465.         if attacker.hasWorkingAbility(:FLOWERGIFT) &&
  3466.            isConst?(attacker.species,PBSpecies,:CHERRIM)
  3467.           atk=(atk*1.5).round
  3468.         end
  3469.         if attacker.pbPartner.hasWorkingAbility(:FLOWERGIFT) &&
  3470.            isConst?(attacker.pbPartner.species,PBSpecies,:CHERRIM)
  3471.           atk=(atk*1.5).round
  3472.         end
  3473.       end
  3474.     end
  3475.     # Attack-boosting items
  3476.     if attacker.hasWorkingItem(:THICKCLUB) &&
  3477.        (isConst?(attacker.species,PBSpecies,:CUBONE) ||
  3478.        isConst?(attacker.species,PBSpecies,:MAROWAK)) && move.pbIsPhysical?(type)
  3479.       atk=(atk*2.0).round
  3480.     end
  3481.     if attacker.hasWorkingItem(:DEEPSEATOOTH) &&
  3482.        isConst?(attacker.species,PBSpecies,:CLAMPERL) && move.pbIsSpecial?(type)
  3483.       atk=(atk*2.0).round
  3484.     end
  3485.     if attacker.hasWorkingItem(:LIGHTBALL) &&
  3486.        isConst?(attacker.species,PBSpecies,:PIKACHU)
  3487.       atk=(atk*2.0).round
  3488.     end
  3489.     if attacker.hasWorkingItem(:SOULDEW) &&
  3490.        (isConst?(attacker.species,PBSpecies,:LATIAS) ||
  3491.        isConst?(attacker.species,PBSpecies,:LATIOS)) && move.pbIsSpecial?(type)
  3492.       atk=(atk*1.5).round
  3493.     end
  3494.     if attacker.hasWorkingItem(:CHOICEBAND) && move.pbIsPhysical?(type)
  3495.       atk=(atk*1.5).round
  3496.     end
  3497.     if attacker.hasWorkingItem(:CHOICESPECS) && move.pbIsSpecial?(type)
  3498.       atk=(atk*1.5).round
  3499.     end
  3500.     # Get base defense stat
  3501.     defense=pbRoughStat(opponent,PBStats::DEFENSE,skill)
  3502.     applysandstorm=false
  3503.     if type>=0 && move.pbIsSpecial?(type)
  3504.       if move.function!=0x122 # Psyshock
  3505.         defense=pbRoughStat(opponent,PBStats::SPDEF,skill)
  3506.         applysandstorm=true
  3507.       end
  3508.     end
  3509.     # Sandstorm weather
  3510.     if skill>=PBTrainerAI.highSkill
  3511.       if pbWeather==PBWeather::SANDSTORM &&
  3512.          opponent.pbHasType?(:ROCK) && applysandstorm
  3513.         defense=(defense*1.5).round
  3514.       end
  3515.     end
  3516.     # Marvel Scale
  3517.     if skill>=PBTrainerAI.bestSkill
  3518.       if opponent.hasWorkingAbility(:MARVELSCALE) &&
  3519.          opponent.status>0 && move.pbIsPhysical?(type)
  3520.         defense=(defense*1.5).round
  3521.       end
  3522.     end
  3523.     # Flower Gift
  3524.     if skill>=PBTrainerAI.bestSkill
  3525.       if pbWeather==PBWeather::SUNNYDAY && move.pbIsSpecial?(type)
  3526.         if opponent.hasWorkingAbility(:FLOWERGIFT) &&
  3527.            isConst?(opponent.species,PBSpecies,:CHERRIM)
  3528.           defense=(defense*1.5).round
  3529.         end
  3530.         if opponent.pbPartner.hasWorkingAbility(:FLOWERGIFT) &&
  3531.            isConst?(opponent.pbPartner.species,PBSpecies,:CHERRIM)
  3532.           defense=(defense*1.5).round
  3533.         end
  3534.       end
  3535.     end
  3536.     # Defense-boosting items
  3537.     if skill>=PBTrainerAI.highSkill
  3538.       if opponent.hasWorkingItem(:EVIOLITE)
  3539.         evos=pbGetEvolvedFormData(opponent.pokemon.fSpecies)
  3540.         if evos && evos.length>0
  3541.           defense=(defense*1.5).round
  3542.         end
  3543.       end
  3544.       if opponent.hasWorkingItem(:DEEPSEASCALE) &&
  3545.          isConst?(opponent.species,PBSpecies,:CLAMPERL) && move.pbIsSpecial?(type)
  3546.         defense=(defense*2.0).round
  3547.       end
  3548.       if opponent.hasWorkingItem(:METALPOWDER) &&
  3549.          isConst?(opponent.species,PBSpecies,:DITTO) &&
  3550.          !opponent.effects[PBEffects::Transform] && move.pbIsPhysical?(type)
  3551.         defense=(defense*2.0).round
  3552.       end
  3553.       if opponent.hasWorkingItem(:SOULDEW) &&
  3554.          (isConst?(opponent.species,PBSpecies,:LATIAS) ||
  3555.          isConst?(opponent.species,PBSpecies,:LATIOS)) && move.pbIsSpecial?(type)
  3556.         defense=(defense*1.5).round
  3557.       end
  3558.     end
  3559.     defense = [defense.round,1].max
  3560.     # Main damage calculation
  3561.     damage=(((2.0*attacker.level/5+2).floor*basedamage*atk/defense).floor/50).floor+2
  3562.     # Multi-targeting attacks
  3563.     if skill>=PBTrainerAI.highSkill
  3564.       if move.pbTargetsMultiple?(attacker)
  3565.         damage=(damage*0.75).round
  3566.       end
  3567.     end
  3568.     # Weather
  3569.     if skill>=PBTrainerAI.mediumSkill
  3570.       case pbWeather
  3571.       when PBWeather::SUNNYDAY
  3572.         if isConst?(type,PBTypes,:FIRE)
  3573.           damage=(damage*1.5).round
  3574.         elsif isConst?(type,PBTypes,:WATER)
  3575.           damage=(damage*0.5).round
  3576.         end
  3577.       when PBWeather::RAINDANCE
  3578.         if isConst?(type,PBTypes,:FIRE)
  3579.           damage=(damage*0.5).round
  3580.         elsif isConst?(type,PBTypes,:WATER)
  3581.           damage=(damage*1.5).round
  3582.         end
  3583.       end
  3584.     end
  3585.     # Critical hits - n/a
  3586.     # Random variance - n/a
  3587.     # STAB
  3588.     if skill>=PBTrainerAI.mediumSkill
  3589.       if attacker.pbHasType?(type)
  3590.         if attacker.hasWorkingAbility(:ADAPTABILITY) &&
  3591.            skill>=PBTrainerAI.highSkill
  3592.           damage=(damage*2).round
  3593.         else
  3594.           damage=(damage*1.5).round
  3595.         end
  3596.       end
  3597.     end
  3598.     # Type effectiveness
  3599.     typemod=pbTypeModifier(type,attacker,opponent)
  3600.     if skill>=PBTrainerAI.highSkill
  3601.       damage=(damage*typemod*1.0/8).round
  3602.     end
  3603.     # Burn
  3604.     if skill>=PBTrainerAI.mediumSkill
  3605.       if attacker.status==PBStatuses::BURN && move.pbIsPhysical?(type) &&
  3606.          !attacker.hasWorkingAbility(:GUTS)
  3607.         damage=(damage*0.5).round
  3608.       end
  3609.     end
  3610.     # Make sure damage is at least 1
  3611.     damage=1 if damage<1
  3612.     # Reflect
  3613.     if skill>=PBTrainerAI.highSkill
  3614.       if opponent.pbOwnSide.effects[PBEffects::Reflect]>0 && move.pbIsPhysical?(type)
  3615.         if !opponent.pbPartner.fainted?
  3616.           damage=(damage*0.66).round
  3617.         else
  3618.           damage=(damage*0.5).round
  3619.         end
  3620.       end
  3621.     end
  3622.     # Light Screen
  3623.     if skill>=PBTrainerAI.highSkill
  3624.       if opponent.pbOwnSide.effects[PBEffects::LightScreen]>0 && move.pbIsSpecial?(type)
  3625.         if !opponent.pbPartner.fainted?
  3626.           damage=(damage*0.66).round
  3627.         else
  3628.           damage=(damage*0.5).round
  3629.         end
  3630.       end
  3631.     end
  3632.     # Multiscale
  3633.     if skill>=PBTrainerAI.bestSkill
  3634.       if opponent.hasWorkingAbility(:MULTISCALE) &&
  3635.          opponent.hp==opponent.totalhp
  3636.         damage=(damage*0.5).round
  3637.       end
  3638.     end
  3639.     # Tinted Lens
  3640.     if skill>=PBTrainerAI.bestSkill
  3641.       if attacker.hasWorkingAbility(:TINTEDLENS) && typemod<8
  3642.         damage=(damage*2.0).round
  3643.       end
  3644.     end
  3645.     # Friend Guard
  3646.     if skill>=PBTrainerAI.bestSkill
  3647.       if opponent.pbPartner.hasWorkingAbility(:FRIENDGUARD)
  3648.         damage=(damage*0.75).round
  3649.       end
  3650.     end
  3651.     # Sniper - n/a
  3652.     # Solid Rock, Filter
  3653.     if skill>=PBTrainerAI.bestSkill
  3654.       if (opponent.hasWorkingAbility(:SOLIDROCK) || opponent.hasWorkingAbility(:FILTER)) &&
  3655.          typemod>8
  3656.         damage=(damage*0.75).round
  3657.       end
  3658.     end
  3659.     # Final damage-altering items
  3660.     if attacker.hasWorkingItem(:METRONOME)
  3661.       if attacker.effects[PBEffects::Metronome]>4
  3662.         damage=(damage*2.0).round
  3663.       else
  3664.         met=1.0+attacker.effects[PBEffects::Metronome]*0.2
  3665.         damage=(damage*met).round
  3666.       end
  3667.     end
  3668.     if attacker.hasWorkingItem(:EXPERTBELT) && typemod>8
  3669.       damage=(damage*1.2).round
  3670.     end
  3671.     if attacker.hasWorkingItem(:LIFEORB)
  3672.       damage=(damage*1.3).round
  3673.     end
  3674.     if typemod>8 && skill>=PBTrainerAI.highSkill
  3675.       if (opponent.hasWorkingItem(:CHOPLEBERRY) && isConst?(type,PBTypes,:FIGHTING)) ||
  3676.          (opponent.hasWorkingItem(:COBABERRY) && isConst?(type,PBTypes,:FLYING)) ||
  3677.          (opponent.hasWorkingItem(:KEBIABERRY) && isConst?(type,PBTypes,:POISON)) ||
  3678.          (opponent.hasWorkingItem(:SHUCABERRY) && isConst?(type,PBTypes,:GROUND)) ||
  3679.          (opponent.hasWorkingItem(:CHARTIBERRY) && isConst?(type,PBTypes,:ROCK)) ||
  3680.          (opponent.hasWorkingItem(:TANGABERRY) && isConst?(type,PBTypes,:BUG)) ||
  3681.          (opponent.hasWorkingItem(:KASIBBERRY) && isConst?(type,PBTypes,:GHOST)) ||
  3682.          (opponent.hasWorkingItem(:BABIRIBERRY) && isConst?(type,PBTypes,:STEEL)) ||
  3683.          (opponent.hasWorkingItem(:OCCABERRY) && isConst?(type,PBTypes,:FIRE)) ||
  3684.          (opponent.hasWorkingItem(:PASSHOBERRY) && isConst?(type,PBTypes,:WATER)) ||
  3685.          (opponent.hasWorkingItem(:RINDOBERRY) && isConst?(type,PBTypes,:GRASS)) ||
  3686.          (opponent.hasWorkingItem(:WACANBERRY) && isConst?(type,PBTypes,:ELECTRIC)) ||
  3687.          (opponent.hasWorkingItem(:PAYAPABERRY) && isConst?(type,PBTypes,:PSYCHIC)) ||
  3688.          (opponent.hasWorkingItem(:YACHEBERRY) && isConst?(type,PBTypes,:ICE)) ||
  3689.          (opponent.hasWorkingItem(:HABANBERRY) && isConst?(type,PBTypes,:DRAGON)) ||
  3690.          (opponent.hasWorkingItem(:COLBURBERRY) && isConst?(type,PBTypes,:DARK))
  3691.         damage=(damage*0.5).round
  3692.       end
  3693.     end
  3694.     if skill>=PBTrainerAI.highSkill
  3695.       if opponent.hasWorkingItem(:CHILANBERRY) && isConst?(type,PBTypes,:NORMAL)
  3696.         damage=(damage*0.5).round
  3697.       end
  3698.     end
  3699.     # pbModifyDamage - TODO
  3700.     # "AI-specific calculations below"
  3701.     # Increased critical hit rates
  3702.     if skill>=PBTrainerAI.mediumSkill
  3703.       c=0
  3704.       c+=attacker.effects[PBEffects::FocusEnergy]
  3705.       c+=1 if move.hasHighCriticalRate?
  3706.       c+=1 if (attacker.inHyperMode? rescue false) && isConst?(self.type,PBTypes,:SHADOW)
  3707.       c+=2 if isConst?(attacker.species,PBSpecies,:CHANSEY) &&
  3708.               attacker.hasWorkingItem(:LUCKYPUNCH)
  3709.       c+=2 if isConst?(attacker.species,PBSpecies,:FARFETCHD) &&
  3710.               attacker.hasWorkingItem(:STICK)
  3711.       c+=1 if attacker.hasWorkingAbility(:SUPERLUCK)
  3712.       c+=1 if attacker.hasWorkingItem(:SCOPELENS)
  3713.       c+=1 if attacker.hasWorkingItem(:RAZORCLAW)
  3714.       c=4 if c>4
  3715.       basedamage+=(basedamage*0.1*c)
  3716.     end
  3717.     return damage
  3718.   end
  3719.  
  3720.   def pbRoughAccuracy(move,attacker,opponent,skill)
  3721.     # Get base accuracy
  3722.     baseaccuracy=move.accuracy
  3723.     if skill>=PBTrainerAI.mediumSkill
  3724.       if pbWeather==PBWeather::SUNNYDAY &&
  3725.          (move.function==0x08 || move.function==0x15) # Thunder, Hurricane
  3726.         accuracy=50
  3727.       end
  3728.     end
  3729.     # Accuracy stages
  3730.     accstage=attacker.stages[PBStats::ACCURACY]
  3731.     accstage=0 if opponent.hasWorkingAbility(:UNAWARE)
  3732.     accuracy=(accstage>=0) ? (accstage+3)*100.0/3 : 300.0/(3-accstage)
  3733.     evastage=opponent.stages[PBStats::EVASION]
  3734.     evastage-=2 if @field.effects[PBEffects::Gravity]>0
  3735.     evastage=-6 if evastage<-6
  3736.     evastage=0 if opponent.effects[PBEffects::Foresight] ||
  3737.                   opponent.effects[PBEffects::MiracleEye] ||
  3738.                   move.function==0xA9 || # Chip Away
  3739.                   attacker.hasWorkingAbility(:UNAWARE)
  3740.     evasion=(evastage>=0) ? (evastage+3)*100.0/3 : 300.0/(3-evastage)
  3741.     accuracy*=baseaccuracy/evasion
  3742.     # Accuracy modifiers
  3743.     if skill>=PBTrainerAI.mediumSkill
  3744.       accuracy*=1.3 if attacker.hasWorkingAbility(:COMPOUNDEYES)
  3745.       accuracy*=1.1 if attacker.hasWorkingAbility(:VICTORYSTAR)
  3746.       if skill>=PBTrainerAI.highSkill
  3747.         partner=attacker.pbPartner
  3748.         accuracy*=1.1 if partner && partner.hasWorkingAbility(:VICTORYSTAR)
  3749.       end
  3750.       accuracy*=1.2 if attacker.effects[PBEffects::MicleBerry]
  3751.       accuracy*=1.1 if attacker.hasWorkingItem(:WIDELENS)
  3752.       if skill>=PBTrainerAI.highSkill
  3753.         accuracy*=0.8 if attacker.hasWorkingAbility(:HUSTLE) &&
  3754.                          move.basedamage>0 &&
  3755.                          move.pbIsPhysical?(move.pbType(move.type,attacker,opponent))
  3756.       end
  3757.       if skill>=PBTrainerAI.bestSkill
  3758.         accuracy/=2 if opponent.hasWorkingAbility(:WONDERSKIN) &&
  3759.                        move.basedamage==0 &&
  3760.                        attacker.pbIsOpposing?(opponent.index)
  3761.         accuracy/=1.2 if opponent.hasWorkingAbility(:TANGLEDFEET) &&
  3762.                          opponent.effects[PBEffects::Confusion]>0
  3763.         accuracy/=1.2 if pbWeather==PBWeather::SANDSTORM &&
  3764.                          opponent.hasWorkingAbility(:SANDVEIL)
  3765.         accuracy/=1.2 if pbWeather==PBWeather::HAIL &&
  3766.                          opponent.hasWorkingAbility(:SNOWCLOAK)
  3767.       end
  3768.       if skill>=PBTrainerAI.highSkill
  3769.         accuracy/=1.1 if opponent.hasWorkingItem(:BRIGHTPOWDER)
  3770.         accuracy/=1.1 if opponent.hasWorkingItem(:LAXINCENSE)
  3771.       end
  3772.     end
  3773.     accuracy=100 if accuracy>100
  3774.     # Override accuracy
  3775.     accuracy=125 if move.accuracy==0   # Doesn't do accuracy check (always hits)
  3776.     accuracy=125 if move.function==0xA5 # Swift
  3777.     if skill>=PBTrainerAI.mediumSkill
  3778.       accuracy=125 if opponent.effects[PBEffects::LockOn]>0 &&
  3779.                       opponent.effects[PBEffects::LockOnPos]==attacker.index
  3780.       if skill>=PBTrainerAI.highSkill
  3781.         accuracy=125 if attacker.hasWorkingAbility(:NOGUARD) ||
  3782.                         opponent.hasWorkingAbility(:NOGUARD)
  3783.       end
  3784.       accuracy=125 if opponent.effects[PBEffects::Telekinesis]>0
  3785.       case pbWeather
  3786.       when PBWeather::HAIL
  3787.         accuracy=125 if move.function==0x0D # Blizzard
  3788.       when PBWeather::RAINDANCE
  3789.         accuracy=125 if move.function==0x08 || move.function==0x15 # Thunder, Hurricane
  3790.       end
  3791.       if move.function==0x70 # OHKO moves
  3792.         accuracy=move.accuracy+attacker.level-opponent.level
  3793.         accuracy=0 if opponent.hasWorkingAbility(:STURDY)
  3794.         accuracy=0 if opponent.level>attacker.level
  3795.       end
  3796.     end
  3797.     return accuracy
  3798.   end
  3799.  
  3800. ################################################################################
  3801. # Choose a move to use.
  3802. ################################################################################
  3803.   def pbChooseMoves(index)
  3804.     attacker=@battlers[index]
  3805.     scores=[0,0,0,0]
  3806.     targets=nil
  3807.     myChoices=[]
  3808.     totalscore=0
  3809.     target=-1
  3810.     skill=0
  3811.     wildbattle=!@opponent && pbIsOpposing?(index)
  3812.     if wildbattle # If wild battle
  3813.       for i in 0...4
  3814.         if pbCanChooseMove?(index,i,false)
  3815.           scores[i]=100
  3816.           myChoices.push(i)
  3817.           totalscore+=100
  3818.         end
  3819.       end
  3820.     else
  3821.       skill=pbGetOwner(attacker.index).skill || 0
  3822.       opponent=attacker.pbOppositeOpposing
  3823.       if @doublebattle && !opponent.fainted? && !opponent.pbPartner.fainted?
  3824.         # Choose a target and move.  Also care about partner.
  3825.         otheropp=opponent.pbPartner
  3826.         scoresAndTargets=[]
  3827.         targets=[-1,-1,-1,-1]
  3828.         for i in 0...4
  3829.           if pbCanChooseMove?(index,i,false)
  3830.             score1=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill)
  3831.             score2=pbGetMoveScore(attacker.moves[i],attacker,otheropp,skill)
  3832.             if (attacker.moves[i].target&0x20)!=0 # Target's user's side
  3833.               if attacker.pbPartner.fainted? # No partner
  3834.                 score1*=5/3
  3835.                 score2*=5/3
  3836.               else
  3837.                 # If this move can also target the partner, get the partner's
  3838.                 # score too
  3839.                 s=pbGetMoveScore(attacker.moves[i],attacker,attacker.pbPartner,skill)
  3840.                 if s>=140 # Highly effective
  3841.                   score1*=1/3
  3842.                   score2*=1/3
  3843.                 elsif s>=100 # Very effective
  3844.                   score1*=2/3
  3845.                   score2*=2/3
  3846.                 elsif s>=40 # Less effective
  3847.                   score1*=4/3
  3848.                   score2*=4/3
  3849.                 else # Hardly effective
  3850.                   score1*=5/3
  3851.                   score2*=5/3
  3852.                 end
  3853.               end
  3854.             end
  3855.             myChoices.push(i)
  3856.             scoresAndTargets.push([i*2,i,score1,opponent.index])
  3857.             scoresAndTargets.push([i*2+1,i,score2,otheropp.index])
  3858.           end
  3859.         end
  3860.         scoresAndTargets.sort!{|a,b|
  3861.            if a[2]==b[2] # if scores are equal
  3862.              a[0]<=>b[0] # sort by index (for stable comparison)
  3863.            else
  3864.              b[2]<=>a[2]
  3865.            end
  3866.         }
  3867.         for i in 0...scoresAndTargets.length
  3868.           idx=scoresAndTargets[i][1]
  3869.           thisScore=scoresAndTargets[i][2]
  3870.           if thisScore>0
  3871.             if scores[idx]==0 || ((scores[idx]==thisScore && pbAIRandom(10)<5) ||
  3872.                (scores[idx]!=thisScore && pbAIRandom(10)<3))
  3873.               scores[idx]=thisScore
  3874.               targets[idx]=scoresAndTargets[i][3]
  3875.             end
  3876.           end
  3877.         end
  3878.         for i in 0...4
  3879.           scores[i]=0 if scores[i]<0
  3880.           totalscore+=scores[i]
  3881.         end
  3882.       else
  3883.         # Choose a move. There is only 1 opposing Pokémon.
  3884.         if @doublebattle && opponent.fainted?
  3885.           opponent=opponent.pbPartner
  3886.         end
  3887.         for i in 0...4
  3888.           if pbCanChooseMove?(index,i,false)
  3889.             scores[i]=pbGetMoveScore(attacker.moves[i],attacker,opponent,skill)
  3890.             myChoices.push(i)
  3891.           end
  3892.           scores[i]=0 if scores[i]<0
  3893.           totalscore+=scores[i]
  3894.         end
  3895.       end
  3896.     end
  3897.     maxscore=0
  3898.     for i in 0...4
  3899.       maxscore=scores[i] if scores[i] && scores[i]>maxscore
  3900.     end
  3901.     # Minmax choices depending on AI
  3902.     if !wildbattle && skill>=PBTrainerAI.mediumSkill
  3903.       threshold=(skill>=PBTrainerAI.bestSkill) ? 1.5 : (skill>=PBTrainerAI.highSkill) ? 2 : 3
  3904.       newscore=(skill>=PBTrainerAI.bestSkill) ? 5 : (skill>=PBTrainerAI.highSkill) ? 10 : 15
  3905.       for i in 0...scores.length
  3906.         if scores[i]>newscore && scores[i]*threshold<maxscore
  3907.           totalscore-=(scores[i]-newscore)
  3908.           scores[i]=newscore
  3909.         end
  3910.       end
  3911.       maxscore=0
  3912.       for i in 0...4
  3913.         maxscore=scores[i] if scores[i] && scores[i]>maxscore
  3914.       end
  3915.     end
  3916.     if $INTERNAL
  3917.       x="[AI] #{attacker.pbThis}'s moves: "
  3918.       j=0
  3919.       for i in 0...4
  3920.         if attacker.moves[i].id!=0
  3921.           x+=", " if j>0
  3922.           x+=PBMoves.getName(attacker.moves[i].id)+"="+scores[i].to_s
  3923.           j+=1
  3924.         end
  3925.       end
  3926.       PBDebug.log(x)
  3927.     end
  3928.     if !wildbattle && maxscore>100
  3929.       stdev=pbStdDev(scores)
  3930.       if stdev>=40 && pbAIRandom(10)!=0
  3931.         # If standard deviation is 40 or more,
  3932.         # there is a highly preferred move. Choose it.
  3933.         preferredMoves=[]
  3934.         for i in 0...4
  3935.           if attacker.moves[i].id!=0 && (scores[i]>=maxscore*0.8 || scores[i]>=200)
  3936.             preferredMoves.push(i)
  3937.             preferredMoves.push(i) if scores[i]==maxscore # Doubly prefer the best move
  3938.           end
  3939.         end
  3940.         if preferredMoves.length>0
  3941.           i=preferredMoves[pbAIRandom(preferredMoves.length)]
  3942.           PBDebug.log("[AI] Prefer #{PBMoves.getName(attacker.moves[i].id)}")
  3943.           pbRegisterMove(index,i,false)
  3944.           target=targets[i] if targets
  3945.           if @doublebattle && target>=0
  3946.             pbRegisterTarget(index,target)
  3947.           end
  3948.           return
  3949.         end
  3950.       end
  3951.     end
  3952.     if !wildbattle && attacker.turncount
  3953.       badmoves=false
  3954.       if ((maxscore<=20 && attacker.turncount>2) ||
  3955.          (maxscore<=30 && attacker.turncount>5)) && pbAIRandom(10)<8
  3956.         badmoves=true
  3957.       end
  3958.       if totalscore<100 && attacker.turncount>1
  3959.         badmoves=true
  3960.         movecount=0
  3961.         for i in 0...4
  3962.           if attacker.moves[i].id!=0
  3963.             if scores[i]>0 && attacker.moves[i].basedamage>0
  3964.               badmoves=false
  3965.             end
  3966.             movecount+=1
  3967.           end
  3968.         end
  3969.         badmoves=badmoves && pbAIRandom(10)!=0
  3970.       end
  3971.       if badmoves
  3972.         # Attacker has terrible moves, try switching instead
  3973.         if pbEnemyShouldWithdrawEx?(index,true)
  3974.           if $INTERNAL
  3975.             PBDebug.log("[AI] Switching due to terrible moves")
  3976.             PBDebug.log([index,@choices[index][0],@choices[index][1],
  3977.                pbCanChooseNonActive?(index),
  3978.                @battlers[index].pbNonActivePokemonCount()].inspect)
  3979.           end
  3980.           return
  3981.         end
  3982.       end
  3983.     end
  3984.     if maxscore<=0
  3985.       # If all scores are 0 or less, choose a move at random
  3986.       if myChoices.length>0
  3987.         pbRegisterMove(index,myChoices[pbAIRandom(myChoices.length)],false)
  3988.       else
  3989.         pbAutoChooseMove(index)
  3990.       end
  3991.     else
  3992.       randnum=pbAIRandom(totalscore)
  3993.       cumtotal=0
  3994.       for i in 0...4
  3995.         if scores[i]>0
  3996.           cumtotal+=scores[i]
  3997.           if randnum<cumtotal
  3998.             pbRegisterMove(index,i,false)
  3999.             target=targets[i] if targets
  4000.             break
  4001.           end
  4002.         end
  4003.       end
  4004.     end
  4005.     PBDebug.log("[AI] Will use #{@choices[index][2].name}") if @choices[index][2]
  4006.     if @doublebattle && target>=0
  4007.       pbRegisterTarget(index,target)
  4008.     end
  4009.   end
  4010.  
  4011. ################################################################################
  4012. # Decide whether the opponent should Mega Evolve their Pokémon.
  4013. ################################################################################
  4014.   def pbEnemyShouldMegaEvolve?(index)
  4015.     # Simple "always should if possible"
  4016.     return pbCanMegaEvolve?(index)
  4017.   end
  4018.  
  4019. ################################################################################
  4020. # Decide whether the opponent should use an item on the Pokémon.
  4021. ################################################################################
  4022.   def pbEnemyShouldUseItem?(index)
  4023.     item=pbEnemyItemToUse(index)
  4024.     if item>0
  4025.       pbRegisterItem(index,item,nil)
  4026.       return true
  4027.     end
  4028.     return false
  4029.   end
  4030.  
  4031.   def pbEnemyItemAlreadyUsed?(index,item,items)
  4032.     if @choices[1][0]==3 && @choices[1][1]==item
  4033.       qty=0
  4034.       for i in items
  4035.         qty+=1 if i==item
  4036.       end
  4037.       return true if qty<=1
  4038.     end
  4039.     return false
  4040.   end
  4041.  
  4042.   def pbEnemyItemToUse(index)
  4043.     return 0 if !@internalbattle
  4044.     items=pbGetOwnerItems(index)
  4045.     return 0 if !items
  4046.     battler=@battlers[index]
  4047.     return 0 if battler.fainted? ||
  4048.                 battler.effects[PBEffects::Embargo]>0
  4049.     hashpitem=false
  4050.     for i in items
  4051.       next if pbEnemyItemAlreadyUsed?(index,i,items)
  4052.       if isConst?(i,PBItems,:POTION) ||
  4053.          isConst?(i,PBItems,:SUPERPOTION) ||
  4054.          isConst?(i,PBItems,:HYPERPOTION) ||
  4055.          isConst?(i,PBItems,:MAXPOTION) ||
  4056.          isConst?(i,PBItems,:FULLRESTORE)
  4057.         hashpitem=true
  4058.       end
  4059.     end
  4060.     for i in items
  4061.       next if pbEnemyItemAlreadyUsed?(index,i,items)
  4062.       if isConst?(i,PBItems,:FULLRESTORE)
  4063.         return i if battler.hp<=battler.totalhp/4
  4064.         return i if battler.hp<=battler.totalhp/2 && pbAIRandom(10)<3
  4065.         return i if battler.hp<=battler.totalhp*2/3 &&
  4066.                     (battler.status>0 || battler.effects[PBEffects::Confusion]>0) &&
  4067.                     pbAIRandom(10)<3
  4068.       elsif isConst?(i,PBItems,:POTION) ||
  4069.          isConst?(i,PBItems,:SUPERPOTION) ||
  4070.          isConst?(i,PBItems,:HYPERPOTION) ||
  4071.          isConst?(i,PBItems,:MAXPOTION)
  4072.         return i if battler.hp<=battler.totalhp/4
  4073.         return i if battler.hp<=battler.totalhp/2 && pbAIRandom(10)<3
  4074.       elsif isConst?(i,PBItems,:FULLHEAL)
  4075.         return i if !hashpitem &&
  4076.                     (battler.status>0 || battler.effects[PBEffects::Confusion]>0)
  4077.       elsif isConst?(i,PBItems,:XATTACK) ||
  4078.             isConst?(i,PBItems,:XDEFEND) ||
  4079.             isConst?(i,PBItems,:XDEFENSE) ||
  4080.             isConst?(i,PBItems,:XSPEED) ||
  4081.             isConst?(i,PBItems,:XSPECIAL) ||
  4082.             isConst?(i,PBItems,:XSPATK) ||
  4083.             isConst?(i,PBItems,:XSPDEF) ||
  4084.             isConst?(i,PBItems,:XACCURACY)
  4085.         stat=0
  4086.         stat=PBStats::ATTACK if isConst?(i,PBItems,:XATTACK)
  4087.         stat=PBStats::DEFENSE if isConst?(i,PBItems,:XDEFEND)
  4088.         stat=PBStats::DEFENSE if isConst?(i,PBItems,:XDEFENSE)
  4089.         stat=PBStats::SPEED if isConst?(i,PBItems,:XSPEED)
  4090.         stat=PBStats::SPATK if isConst?(i,PBItems,:XSPECIAL)
  4091.         stat=PBStats::SPATK if isConst?(i,PBItems,:XSPATK)
  4092.         stat=PBStats::SPDEF if isConst?(i,PBItems,:XSPDEF)
  4093.         stat=PBStats::ACCURACY if isConst?(i,PBItems,:XACCURACY)
  4094.         if stat>0 && !battler.pbTooHigh?(stat)
  4095.           return i if pbAIRandom(10)<3-battler.stages[stat]
  4096.         end
  4097.       end
  4098.     end
  4099.     return 0
  4100.   end
  4101.  
  4102. ################################################################################
  4103. # Decide whether the opponent should switch Pokémon.
  4104. ################################################################################
  4105.   def pbEnemyShouldWithdraw?(index)
  4106. #    if $INTERNAL && !pbIsOpposing?(index)
  4107. #      return pbEnemyShouldWithdrawOld?(index)
  4108. #    end
  4109.     return pbEnemyShouldWithdrawEx?(index,false)
  4110.   end
  4111.  
  4112.   def pbEnemyShouldWithdrawEx?(index,alwaysSwitch)
  4113.     return false if !@opponent
  4114.     shouldswitch=alwaysSwitch
  4115.     typecheck=false
  4116.     batonpass=-1
  4117.     movetype=-1
  4118.     skill=pbGetOwner(index).skill || 0
  4119.     if @opponent && !shouldswitch && @battlers[index].turncount>0
  4120.       if skill>=PBTrainerAI.highSkill
  4121.         opponent=@battlers[index].pbOppositeOpposing
  4122.         opponent=opponent.pbPartner if opponent.fainted?
  4123.         if !opponent.fainted? && opponent.lastMoveUsed>0 &&
  4124.            (opponent.level-@battlers[index].level).abs<=6
  4125.           move=PBMoveData.new(opponent.lastMoveUsed)
  4126.           typemod=pbTypeModifier(move.type,@battlers[index],@battlers[index])
  4127.           movetype=move.type
  4128.           if move.basedamage>70 && typemod>8
  4129.             shouldswitch=(pbAIRandom(100)<30)
  4130.           elsif move.basedamage>50 && typemod>8
  4131.             shouldswitch=(pbAIRandom(100)<20)
  4132.           end
  4133.         end
  4134.       end
  4135.     end
  4136.     if !pbCanChooseMove?(index,0,false) &&
  4137.        !pbCanChooseMove?(index,1,false) &&
  4138.        !pbCanChooseMove?(index,2,false) &&
  4139.        !pbCanChooseMove?(index,3,false) &&
  4140.        @battlers[index].turncount &&
  4141.        @battlers[index].turncount>5
  4142.       shouldswitch=true
  4143.     end
  4144.     if skill>=PBTrainerAI.highSkill && @battlers[index].effects[PBEffects::PerishSong]!=1
  4145.       for i in 0...4
  4146.         move=@battlers[index].moves[i]
  4147.         if move.id!=0 && pbCanChooseMove?(index,i,false) &&
  4148.           move.function==0xED # Baton Pass
  4149.           batonpass=i
  4150.           break
  4151.         end
  4152.       end
  4153.     end
  4154.     if skill>=PBTrainerAI.highSkill
  4155.       if @battlers[index].status==PBStatuses::POISON &&
  4156.          @battlers[index].statusCount>0
  4157.         toxicHP=(@battlers[index].totalhp/16)
  4158.         nextToxicHP=toxicHP*(@battlers[index].effects[PBEffects::Toxic]+1)
  4159.         if nextToxicHP>=@battlers[index].hp &&
  4160.            toxicHP<@battlers[index].hp && pbAIRandom(100)<80
  4161.           shouldswitch=true
  4162.         end
  4163.       end
  4164.     end
  4165.     if skill>=PBTrainerAI.mediumSkill
  4166.       if @battlers[index].effects[PBEffects::Encore]>0
  4167.         scoreSum=0
  4168.         scoreCount=0
  4169.         attacker=@battlers[index]
  4170.         encoreIndex=@battlers[index].effects[PBEffects::EncoreIndex]
  4171.         if !attacker.pbOpposing1.fainted?
  4172.           scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
  4173.              attacker,attacker.pbOpposing1,skill)
  4174.           scoreCount+=1
  4175.         end
  4176.         if !attacker.pbOpposing2.fainted?
  4177.           scoreSum+=pbGetMoveScore(attacker.moves[encoreIndex],
  4178.              attacker,attacker.pbOpposing2,skill)
  4179.           scoreCount+=1
  4180.         end
  4181.         if scoreCount>0 && scoreSum/scoreCount<=20 && pbAIRandom(10)<8
  4182.           shouldswitch=true
  4183.         end
  4184.       end
  4185.     end
  4186.     if skill>=PBTrainerAI.highSkill
  4187.       if !@doublebattle && !@battlers[index].pbOppositeOpposing.fainted?
  4188.         opp=@battlers[index].pbOppositeOpposing
  4189.         if (opp.effects[PBEffects::HyperBeam]>0 ||
  4190.            (opp.hasWorkingAbility(:TRUANT) &&
  4191.            opp.effects[PBEffects::Truant])) && pbAIRandom(100)<80
  4192.           shouldswitch=false
  4193.         end
  4194.       end
  4195.     end
  4196.     if @rules["suddendeath"]
  4197.       if @battlers[index].hp<=(@battlers[index].totalhp/4) && pbAIRandom(10)<3 &&
  4198.          @battlers[index].turncount>0
  4199.         shouldswitch=true
  4200.       elsif @battlers[index].hp<=(@battlers[index].totalhp/2) && pbAIRandom(10)<8 &&
  4201.          @battlers[index].turncount>0
  4202.         shouldswitch=true
  4203.       end
  4204.     end
  4205.     if @battlers[index].effects[PBEffects::PerishSong]==1
  4206.       shouldswitch=true
  4207.     end
  4208.     if shouldswitch
  4209.       list=[]
  4210.       party=pbParty(index)
  4211.       for i in 0...party.length
  4212.         if pbCanSwitch?(index,i,false)
  4213.           # If perish count is 1, it may be worth it to switch
  4214.           # even with Spikes, since Perish Song's effect will end
  4215.           if @battlers[index].effects[PBEffects::PerishSong]!=1
  4216.             # Will contain effects that recommend against switching
  4217.             spikes=@battlers[index].pbOwnSide.effects[PBEffects::Spikes]
  4218.             if (spikes==1 && party[i].hp<=(party[i].totalhp/8)) ||
  4219.                (spikes==2 && party[i].hp<=(party[i].totalhp/6)) ||
  4220.                (spikes==3 && party[i].hp<=(party[i].totalhp/4))
  4221.               if !party[i].hasType?(:FLYING) &&
  4222.                  !party[i].hasWorkingAbility(:LEVITATE)
  4223.                 # Don't switch to this if too little HP
  4224.                 next
  4225.               end
  4226.             end
  4227.           end
  4228.           if movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])==0
  4229.             weight=65
  4230.             if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)>8
  4231.               # Greater weight if new Pokemon's type is effective against opponent
  4232.               weight=85
  4233.             end
  4234.             if pbAIRandom(100)<weight
  4235.               list.unshift(i) # put this Pokemon first
  4236.             end
  4237.           elsif movetype>=0 && pbTypeModifier(movetype,@battlers[index],@battlers[index])<8
  4238.             weight=40
  4239.             if pbTypeModifier2(party[i],@battlers[index].pbOppositeOpposing)>8
  4240.               # Greater weight if new Pokemon's type is effective against opponent
  4241.               weight=60
  4242.             end
  4243.             if pbAIRandom(100)<weight
  4244.               list.unshift(i) # put this Pokemon first
  4245.             end
  4246.           else
  4247.             list.push(i) # put this Pokemon last
  4248.           end
  4249.         end
  4250.       end
  4251.       if list.length>0
  4252.         if batonpass!=-1
  4253.           if !pbRegisterMove(index,batonpass,false)
  4254.             return pbRegisterSwitch(index,list[0])
  4255.           end
  4256.           return true
  4257.         else
  4258.           return pbRegisterSwitch(index,list[0])
  4259.         end
  4260.       end
  4261.     end
  4262.     return false
  4263.   end
  4264.  
  4265.   def pbDefaultChooseNewEnemy(index,party)
  4266.     enemies=[]
  4267.     for i in 0..party.length-1
  4268.       if pbCanSwitchLax?(index,i,false)
  4269.         enemies.push(i)
  4270.       end
  4271.     end
  4272.     if enemies.length>0
  4273.       return pbChooseBestNewEnemy(index,party,enemies)
  4274.     end
  4275.     return -1
  4276.   end
  4277.  
  4278.   def pbChooseBestNewEnemy(index,party,enemies)
  4279.     return -1 if !enemies || enemies.length==0
  4280.     $PokemonTemp=PokemonTemp.new if !$PokemonTemp
  4281.     o1=@battlers[index].pbOpposing1
  4282.     o2=@battlers[index].pbOpposing2
  4283.     o1=nil if o1 && o1.fainted?
  4284.     o2=nil if o2 && o2.fainted?
  4285.     best=-1
  4286.     bestSum=0
  4287.     for e in enemies
  4288.       pkmn=party[e]
  4289.       sum=0
  4290.       for move in pkmn.moves
  4291.         next if move.id==0
  4292.         md=PBMoveData.new(move.id)
  4293.         next if md.basedamage==0
  4294.         if o1
  4295.           sum+=PBTypes.getCombinedEffectiveness(md.type,o1.type1,o1.type2,o1.effects[PBEffects::Type3])
  4296.         end
  4297.         if o2
  4298.           sum+=PBTypes.getCombinedEffectiveness(md.type,o2.type1,o2.type2,o2.effects[PBEffects::Type3])
  4299.         end
  4300.       end
  4301.       if best==-1 || sum>bestSum
  4302.         best=e
  4303.         bestSum=sum
  4304.       end
  4305.     end
  4306.     return best
  4307.   end
  4308.  
  4309. ################################################################################
  4310. # Choose an action.
  4311. ################################################################################
  4312.   def pbDefaultChooseEnemyCommand(index)
  4313.     if !pbCanShowFightMenu?(index)
  4314.       return if pbEnemyShouldUseItem?(index)
  4315.       return if pbEnemyShouldWithdraw?(index)
  4316.       pbAutoChooseMove(index)
  4317.       return
  4318.     else
  4319.       return if pbEnemyShouldUseItem?(index)
  4320.       return if pbEnemyShouldWithdraw?(index)
  4321.       return if pbAutoFightMenu(index)
  4322.       pbRegisterMegaEvolution(index) if pbEnemyShouldMegaEvolve?(index)
  4323.       pbChooseMoves(index)
  4324.     end
  4325.   end
  4326.  
  4327. ################################################################################
  4328. # Other functions.
  4329. ################################################################################
  4330.   def pbDbgPlayerOnly?(idx)
  4331.     return true if !$INTERNAL
  4332.     return pbOwnedByPlayer?(idx.index) if idx.respond_to?("index")
  4333.     return pbOwnedByPlayer?(idx)
  4334.   end
  4335.  
  4336.   def pbStdDev(scores)
  4337.     n=0
  4338.     sum=0
  4339.     scores.each{|s| sum+=s; n+=1 }
  4340.     return 0 if n==0
  4341.     mean=sum.to_f/n.to_f
  4342.     varianceTimesN=0
  4343.     for i in 0...scores.length
  4344.       if scores[i]>0
  4345.         deviation=scores[i].to_f-mean
  4346.         varianceTimesN+=deviation*deviation
  4347.       end
  4348.     end
  4349.     # Using population standard deviation
  4350.     # [(n-1) makes it a sample std dev, would be 0 with only 1 sample]
  4351.     return Math.sqrt(varianceTimesN/n)
  4352.   end
  4353. end
Add Comment
Please, Sign In to add comment