Resource icon

Teach the AI to Use Revives

Pokémon Essentials Version
v17.2 ✅
In Essentials, as in the original Pokemon games, you will never battle an opponent who uses a Revive. Even if you give a trainer a revival item, they'll never use it. That's because the AI hasn't been programmed to know how to revive. I found that, in my game, I had some story reasons for wanting a few NPC's to be able to use Revives in battle. So, I wrote a script to make that possible:



This is a fairly simple plug & play script, but I do want to at least give a word of caution to those who use it. Because NPC's have never used revives in the official games, it might really blindside your players if they are used without warning in your game. And it can seem really unfair if NPC's spam revives (even if the player is allowed to do that themselves).
So while you can certainly use this script to add a high degree of difficulty to your game, I recommend handing out the revival items to your NPC's sparingly - perhaps just to Gym Leaders and the Elite Four or to Evil Team Admins. And find a way to prepare the player for the possibility beforehand so that the game still feels fair.

And now, with that out of the way, here's the script to insert into a script section above Main:
Ruby:
class PokeBattle_Battle

  alias oldEnemyItem pbEnemyUseItem
  def pbEnemyUseItem(item,battler)
    oldEnemyItem(item,battler)
    if isConst?(item,PBItems,:REVIVE) ||
        isConst?(item,PBItems,:MAXREVIVE) ||
        isConst?(item,PBItems,:REVIVALHERB)
      pbDisplay(_INTL("{1} revived a fainted Pokémon!",opponent.fullname))
    elsif isConst?(item,PBItems,:SACREDASH)
      pbDisplay(_INTL("{1} revived all fainted Pokémon!",opponent.fullname))
    end
  end

  alias oldEnemyItemAI pbEnemyItemToUse
  def pbEnemyItemToUse(index)
    return 0 if !@internalbattle
    items=pbGetOwnerItems(index)
    return 0 if !items
    party=pbParty(index)
    for i in items
      next if pbEnemyItemAlreadyUsed?(index,i,items)
      if isConst?(i,PBItems,:REVIVE) ||
          isConst?(i,PBItems,:MAXREVIVE) ||
          isConst?(i,PBItems,:REVIVALHERB)
        skill=pbGetOwner(index).skill || 0
        fainters=[]
        rpkmn = -1
        for j in 0...party.length
          fainters.push(j) if party[j].fainted?
        end
        if skill>=PBTrainerAI.highSkill
          if fainters.length==party.length-1
                o1=@battlers[index].pbOpposing1
                o2=@battlers[index].pbOpposing2
                o1=nil if o1 && o1.fainted?
                o2=nil if o2 && o2.fainted?
                best=-1
                bestSum=0
                bestStat=0
                for e in fainters
                  pkmn=party[e]
                  sum=0
                  statTotal=0
                  for move in pkmn.moves
                    next if move.id==0
                    md=PBMoveData.new(move.id)
                    next if md.basedamage==0
                    if o1
                      sum+=PBTypes.getCombinedEffectiveness(md.type,o1.type1,o1.type2,o1.effects[PBEffects::Type3])
                      statTotal+=party[e].totalhp
                      statTotal+=party[e].attack
                      statTotal+=party[e].defense
                      statTotal+=party[e].speed
                      statTotal+=party[e].spatk
                      statTotal+=party[e].spdef
                    end
                    if o2
                      sum+=PBTypes.getCombinedEffectiveness(md.type,o2.type1,o2.type2,o2.effects[PBEffects::Type3])
                      statTotal+=party[e].totalhp
                      statTotal+=party[e].attack
                      statTotal+=party[e].defense
                      statTotal+=party[e].speed
                      statTotal+=party[e].spatk
                      statTotal+=party[e].spdef
                    end
                  end
                  if best==-1 || sum>bestSum
                    best=e
                    bestSum=sum
                    bestStat=statTotal
                  elsif sum == bestSum
                    if statTotal>bestStat
                      best=e
                      bestStat=statTotal
                    end
                  end
                end
            rpkmn=party[best]
          end
        elsif skill>=PBTrainerAI.mediumSkill
          if (fainters.length * 2) >= party.length
            currentstatTotal=0
            for j in fainters
              statTotal=0
              statTotal+=party[j].totalhp
              statTotal+=party[j].attack
              statTotal+=party[j].defense
              statTotal+=party[j].speed
              statTotal+=party[j].spatk
              statTotal+=party[j].spdef
              if statTotal>currentstatTotal
                currentstatTotal=statTotal
                rpkmn=party[j]
              end
            end
          end
        elsif fainters.length>0
          faintindex=fainters[rand(fainters.length)]
          rpkmn=party[faintindex]
        end
        if rpkmn != -1
          if isConst?(i,PBItems,:REVIVE)
            rpkmn.hp=(rpkmn.totalhp/2).floor
            return i
          elsif isConst?(i,PBItems,:MAXREVIVE)|| isConst?(i,PBItems,:REVIVALHERB)
            rpkmn.hp=rpkmn.totalhp
            return i
          end
        end
      end
    end
    regularItem=oldEnemyItemAI(index)
    return regularItem if regularItem>0
    for i in items
      if isConst?(i,PBItems,:SACREDASH)
        numFainted=0
        for j in 0...party.length
          if party[j].fainted?
            numFainted+=1
          end
        end
        if numFainted>0
          for j in 0...party.length
            party[j].hp=party[j].totalhp if party[j].fainted?
          end
          return i
        end
      end
    end
    return 0
  end

end

After that, all you have to do is give a revival item to a trainer in trainers.txt (and make sure that trainer has more than one pokémon in its party), and you're good to go.
  • High Skill Trainer - waits until they are down to one Pokémon, then revives the fainted Pokémon with the best type advantage and highest stats.
  • Medium Skill Trainer - waits until half the party is fainted, then revives the fainted Pokémon with the highest stats.
  • Low Skill Trainers - revive the first Pokémon that faints.
Enjoy!
Credits
Poq
Author
Poq
First release
Last update
Rating
5.00 star(s) 1 ratings

Latest updates

  1. v1.2

    Fixing a minor bug that caused errors in wild battles.
  2. v1.1 Even Smarter AI

    The script now takes into account trainer skill level. High Skill Trainer - waits until they...

Latest reviews

My God! If I play a game that has this and at the time of the fight I read that my opponent used revive, I would say: "-WHAAT ?!" - however it would look very good! This will cause the player to prepare more (if he loses or wins, thinking that the next one will also have Revive). Thanks for sharing!
Top