• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Custom trainer battles

1,405
Posts
11
Years
  • You should put the example trainer type to a 1-71 number because otherwise people trying the script out without changing it will get an error saying the trainer type doesn't exist (in the most complicated error possible)

    Scripts works fine and i will def use it in my Pokemon game(with credit of course) to save time making trainer battles.
     

    Florio

    Pokemon Crimson Skies Owner
    391
    Posts
    15
    Years
  • Honestly this script seems somewhat unnecessary. Editing the PBS is easy enough, and if you make your Trainer's VIA this method then you can't easily change the Pokemon after. Sometimes I change around the Pokemon in my game and the Trainer's to and Ctrl+H and Ctrl+F come in handy while using the trainers PBS file. I feel like this would make the game more unorganized overall. But still, it seems useful for people who aren't as accustomed to Essentials.
     
    199
    Posts
    14
    Years
    • Seen Jul 6, 2022
    I tried to create a trainer but it causes error message.

    Spoiler:


    Spoiler:



    EDIT: I changed "pokemon.calcStats" for "p0.calcStats" and it fixed up.
    But when the trainer is going to use the Pokemon in battle, another error message:

    Spoiler:
     
    Last edited:

    Maruno

    Lead Dev of Pokémon Essentials
    5,285
    Posts
    16
    Years
  • p0.moves = PBMoves::THUNDER
    p0.moves = PBMoves::SURF
    p0.moves = PBMoves::GRASSKNOT
    p0.moves = PBMoves::HIDDENPOWER
    That's not how you teach moves to a Pokémon. Try reading the Essentials wiki and/or looking at how the demo Pokémon are given movesets full of HMs (in def pbCreatePokemon).
     

    NeoPlayerX

    Julie_Haru
    9
    Posts
    9
    Years
    • Seen Mar 12, 2023
    Sure, it's not hard. Insert this method in the script.

    Code:
    # ------------------------------------------------------------------------------
    # Returns a random element from a given array.
    # ------------------------------------------------------------------------------
    def randomElement(array)
      i = rand(array.length)
      return array[i]
    end

    Then, in the event, instead of writing createPokemon("PIKACHU", 13) you can write
    createPokemon(randomElement(SomePool), 13), and you'll need to define 'SomePool',
    either in the event script or in a global script (such as CustomTrainers) as,
    Code:
    SomePool = ["PIKACHU", "BULBASAUR", "SOME_OTHER_POKEMON"]



    Sorry, I don't understand. Do you want me to describe functions better?

    To put all the Pokémon at once in the "array" instead of putting one by one?

    Instead of placing: SomePool = [Bulbasaur, Ivysaur ...]
    Place: SomePool = [Bulbasaur ... Zygard]

    It's possible?

    Thanks
     
    20
    Posts
    9
    Years
    • Seen Apr 26, 2020
    it might be possible to add that the duelist just sees the player approaches to fight
     
    824
    Posts
    8
    Years
  • Honestly this script seems somewhat unnecessary. Editing the PBS is easy enough, and if you make your Trainer's VIA this method then you can't easily change the Pokemon after. Sometimes I change around the Pokemon in my game and the Trainer's to and Ctrl+H and Ctrl+F come in handy while using the trainers PBS file. I feel like this would make the game more unorganized overall. But still, it seems useful for people who aren't as accustomed to Essentials.

    I plan on using this only for "dynamic" trainers. Characters like your rival where your choices affect their party. Rather than defining a slot for him in the PBS files for each encounter, each starter, and each Eeveeloution, and have a convoluted mess of conditional branches in each event, I'm going to just have him dynamically create his party at each encounter. You picked this starter? Okay, add these two pokemon to his party. You evolved your plot Eevee into this? Add these two pokemon. You're playing as a female? Make this member of his team male.

    Standard trainers who are going to have the same Pokemon no matter what you choose see going to stay in the PBS files.
     
    Last edited:
    22
    Posts
    8
    Years
    • Seen Feb 1, 2017
    Is there a way to add support for the gen 6 battle mechanics, the one's found in the pokemon essentials gen6.
    Amazing job by the way.
     
    824
    Posts
    8
    Years
  • Is there a way to add support for the gen 6 battle mechanics, the one's found in the pokemon essentials gen6.
    Amazing job by the way.

    Code:
    # ------------------------------------------------------------------------------
    # Written by Stochastic, except for customTrainerBattle method which is a
    # modified version of pbTrainerBattle method.
    # ------------------------------------------------------------------------------
    
    BR_DRAW = 5
    BR_LOSS = 2
    BR_WIN = 1
    
    # ------------------------------------------------------------------------------
    # species - Name of the species, e.g. "PIKACHU"
    # level - Level
    # moveset - Optional. Array of moves, e.g. [:MUDSLAP, :THUNDERBOLT, :VINEWHIP]
    # If not specified, pokemon will be created with moves learned by leveling.
    # The pokemon doesn't need to be able to learn the given moves, they can be
    # arbitary.
    # ------------------------------------------------------------------------------
    def createPokemon(species, level, moveset=nil)
      begin
        poke = PokeBattle_Pokemon.new(species, level)
        poke.moves = convertMoves(moveset) if moveset
        poke.shinyflag = false
        return poke
      rescue
        return PokeBattle_Pokemon.new("PIKACHU", 5)
      end
    end
    
    def convertMoves(moves)
      moves.map! {|m| PBMove.new(getMoveID(m))}
      return moves
    end
    
    # provide move like this; :TACKLE
    def getMoveID(move)
      return getConst(PBMoves,move)
    end
    
    # ------------------------------------------------------------------------------
    # Creates a trainer with specified id, name, party, and optionally, items.
    # Does not depend on defined trainers, only on trainer types
    # ------------------------------------------------------------------------------
    def createTrainer(trainerid,trainername,party,items=[])
      
      name = pbGetMessageFromHash(MessageTypes::TrainerNames, trainername)
      opponent = PokeBattle_Trainer.new(name, trainerid)
      opponent.setForeignID($Trainer) if $Trainer
      opponent.party = party
      
      return [opponent,items,party]
    end
    
    # ------------------------------------------------------------------------------
    # Initiates trainer battle. This is a modified pbTrainerBattle method.
    #
    # trainer - custom PokeBattle_Trainer provided by the user
    # endspeech - what the trainer says in-battle when defeated
    # doublebattle - Optional. Set it to true if you want a double battle
    # canlose - Optional. Set it to true if you want your party to be healed after battle,
    # and if you don't want to be sent to a pokemon center if you lose
    # ------------------------------------------------------------------------------
    def customTrainerBattle(trainer,endspeech,doublebattle=false,canlose=false,
                            skybattle=false,inverse=false)
       # Sky battle eligibility for player
      if skybattle
        count=0
        for poke in $Trainer.party
          count+=1 if pbCanSkyBattle?(poke)
        end
        if count==0
          Kernel.pbMessage(_INTL("You don't have any eligible pokemon for a sky battle"))
          return false
        end
      end
      trainerparty=0 # added by SH
      if $Trainer.pokemonCount==0
        Kernel.pbMessage(_INTL("SKIPPING BATTLE...")) if $DEBUG
        return BR_LOSS # changed by SH
      end
      if !$PokemonTemp.waitingTrainer && $Trainer.ablePokemonCount>1 &&
        pbMapInterpreterRunning?
        thisEvent=pbMapInterpreter.get_character(0)
        triggeredEvents=$game_player.pbTriggeredTrainerEvents([2],false)
        otherEvent=[]
        for i in triggeredEvents
          if i.id!=thisEvent.id && !$game_self_switches[[$game_map.map_id,i.id,"A"]]
            otherEvent.push(i)
          end
        end
        if otherEvent.length==1
          if trainer[2].length<=3
            $PokemonTemp.waitingTrainer=[trainer,thisEvent.id,endspeech,doublebattle]
            return BR_LOSS # changed by SH
          end
        end
      end
      
      if $PokemonGlobal.partner && ($PokemonTemp.waitingTrainer || doublebattle)
        othertrainer=PokeBattle_Trainer.new(
          $PokemonGlobal.partner[1],$PokemonGlobal.partner[0])
        othertrainer.id=$PokemonGlobal.partner[2]
        othertrainer.party=$PokemonGlobal.partner[3]
        playerparty=[]
        for i in 0...$Trainer.party.length
          playerparty[i]=$Trainer.party[i]
        end
        for i in 0...othertrainer.party.length
          playerparty[6+i]=othertrainer.party[i]
        end
        fullparty1=true
        playertrainer=[$Trainer,othertrainer]
        doublebattle=true
      else
        playerparty=$Trainer.party
        playertrainer=$Trainer
        fullparty1=false
      end
      if $PokemonTemp.waitingTrainer
        combinedParty=[]
        fullparty2=false
        if false
          if $PokemonTemp.waitingTrainer[0][2].length>3
            raise _INTL("Opponent 1's party has more than three Pokémon, which is not allowed")
          end
          if trainer[2].length>3
            raise _INTL("Opponent 2's party has more than three Pokémon, which is not allowed")
          end
        elsif $PokemonTemp.waitingTrainer[0][2].length>3 || trainer[2].length>3
          for i in 0...$PokemonTemp.waitingTrainer[0][2].length
            combinedParty[i]=$PokemonTemp.waitingTrainer[0][2][i]
          end
          for i in 0...trainer[2].length
            combinedParty[6+i]=trainer[2][i]
          end
          fullparty2=true
        else
          for i in 0...$PokemonTemp.waitingTrainer[0][2].length
            combinedParty[i]=$PokemonTemp.waitingTrainer[0][2][i]
          end
          for i in 0...trainer[2].length
            combinedParty[3+i]=trainer[2][i]
          end
          fullparty2=false
        end
        #Sky battle eligibility for opponent
        if skybattle
          count=0
          for poke in combinedParty
            count+=1 if pbCanSkyBattle?(poke)
          end
          if count==0
            Kernel.pbMessage(_INTL("The opponents don't have any eligible pokemon for a sky battle"))
            return false
          end
        end
        scene=pbNewBattleScene
        battle=PokeBattle_Battle.new(scene,playerparty,combinedParty,playertrainer,
          [$PokemonTemp.waitingTrainer[0][0],trainer[0]],skybattle,inverse,gen)
        trainerbgm=pbGetTrainerBattleBGM(
          [$PokemonTemp.waitingTrainer[0][0],trainer[0]])
        battle.fullparty1=fullparty1
        battle.fullparty2=fullparty2
        battle.doublebattle=battle.pbDoubleBattleAllowed?()
        battle.endspeech=$PokemonTemp.waitingTrainer[2]
        battle.endspeech2=endspeech
        battle.items=[$PokemonTemp.waitingTrainer[0][1],trainer[1]]
      else
        #Sky battle eligibility for opponent
        if skybattle
          count=0
          for poke in trainer[2]
            count+=1 if pbCanSkyBattle?(poke)
          end
          if count==0
            Kernel.pbMessage(_INTL("The opponents don't have any eligible pokemon for a sky battle"))
            return false
          end
        end
        scene=pbNewBattleScene
        battle=PokeBattle_Battle.new(scene,playerparty,trainer[2],playertrainer,trainer[0],skybattle,inverse)
        battle.fullparty1=fullparty1
        battle.doublebattle=doublebattle ? battle.pbDoubleBattleAllowed?() : false
        battle.endspeech=endspeech
        battle.items=trainer[1]
        trainerbgm=pbGetTrainerBattleBGM(trainer[0])
      end
      if Input.press?(Input::CTRL) && $DEBUG
        Kernel.pbMessage(_INTL("SKIPPING BATTLE..."))
        Kernel.pbMessage(_INTL("AFTER LOSING..."))
        Kernel.pbMessage(battle.endspeech)
        Kernel.pbMessage(battle.endspeech2) if battle.endspeech2
        if $PokemonTemp.waitingTrainer
          pbMapInterpreter.pbSetSelfSwitch(
            $PokemonTemp.waitingTrainer[1],"A",true
          )
          $PokemonTemp.waitingTrainer=nil
        end
        return BR_WIN # changed by SH
      end
      Events.onStartBattle.trigger(nil,nil)
      battle.internalbattle=true
      pbPrepareBattle(battle)
      restorebgm=true
      decision=0
      pbBattleAnimation(trainerbgm,trainer[0].trainertype,trainer[0].name) { 
        pbSceneStandby {
            decision=battle.pbStartBattle(canlose)
        }
        if $PokemonGlobal.partner
          pbHealAll
          for i in $PokemonGlobal.partner[3]; i.heal; end
        end
        if decision==2 || decision==5
          if canlose
            for i in $Trainer.party; i.heal; end
            for i in 0...10
              Graphics.update
            end
          else
            $game_system.bgm_unpause
            $game_system.bgs_unpause
            Kernel.pbStartOver
          end
        else
          Events.onEndBattle.trigger(nil,decision)
          if decision==1
            if $PokemonTemp.waitingTrainer
              pbMapInterpreter.pbSetSelfSwitch(
                  $PokemonTemp.waitingTrainer[1],"A",true
              )
            end
          end
        end
      }
      Input.update
      $PokemonTemp.waitingTrainer=nil
      return decision  # changed by SH
    end
     
    22
    Posts
    8
    Years
    • Seen Feb 1, 2017
    Code:
    # ------------------------------------------------------------------------------
    # Written by Stochastic, except for customTrainerBattle method which is a
    # modified version of pbTrainerBattle method.
    # ------------------------------------------------------------------------------
    
    BR_DRAW = 5
    BR_LOSS = 2
    BR_WIN = 1
    
    # ------------------------------------------------------------------------------
    # species - Name of the species, e.g. "PIKACHU"
    # level - Level
    # moveset - Optional. Array of moves, e.g. [:MUDSLAP, :THUNDERBOLT, :VINEWHIP]
    # If not specified, pokemon will be created with moves learned by leveling.
    # The pokemon doesn't need to be able to learn the given moves, they can be
    # arbitary.
    # ------------------------------------------------------------------------------
    def createPokemon(species, level, moveset=nil)
      begin
        poke = PokeBattle_Pokemon.new(species, level)
        poke.moves = convertMoves(moveset) if moveset
        poke.shinyflag = false
        return poke
      rescue
        return PokeBattle_Pokemon.new("PIKACHU", 5)
      end
    end
    
    def convertMoves(moves)
      moves.map! {|m| PBMove.new(getMoveID(m))}
      return moves
    end
    
    # provide move like this; :TACKLE
    def getMoveID(move)
      return getConst(PBMoves,move)
    end
    
    # ------------------------------------------------------------------------------
    # Creates a trainer with specified id, name, party, and optionally, items.
    # Does not depend on defined trainers, only on trainer types
    # ------------------------------------------------------------------------------
    def createTrainer(trainerid,trainername,party,items=[])
      
      name = pbGetMessageFromHash(MessageTypes::TrainerNames, trainername)
      opponent = PokeBattle_Trainer.new(name, trainerid)
      opponent.setForeignID($Trainer) if $Trainer
      opponent.party = party
      
      return [opponent,items,party]
    end
    
    # ------------------------------------------------------------------------------
    # Initiates trainer battle. This is a modified pbTrainerBattle method.
    #
    # trainer - custom PokeBattle_Trainer provided by the user
    # endspeech - what the trainer says in-battle when defeated
    # doublebattle - Optional. Set it to true if you want a double battle
    # canlose - Optional. Set it to true if you want your party to be healed after battle,
    # and if you don't want to be sent to a pokemon center if you lose
    # ------------------------------------------------------------------------------
    def customTrainerBattle(trainer,endspeech,doublebattle=false,canlose=false,
                            skybattle=false,inverse=false)
       # Sky battle eligibility for player
      if skybattle
        count=0
        for poke in $Trainer.party
          count+=1 if pbCanSkyBattle?(poke)
        end
        if count==0
          Kernel.pbMessage(_INTL("You don't have any eligible pokemon for a sky battle"))
          return false
        end
      end
      trainerparty=0 # added by SH
      if $Trainer.pokemonCount==0
        Kernel.pbMessage(_INTL("SKIPPING BATTLE...")) if $DEBUG
        return BR_LOSS # changed by SH
      end
      if !$PokemonTemp.waitingTrainer && $Trainer.ablePokemonCount>1 &&
        pbMapInterpreterRunning?
        thisEvent=pbMapInterpreter.get_character(0)
        triggeredEvents=$game_player.pbTriggeredTrainerEvents([2],false)
        otherEvent=[]
        for i in triggeredEvents
          if i.id!=thisEvent.id && !$game_self_switches[[$game_map.map_id,i.id,"A"]]
            otherEvent.push(i)
          end
        end
        if otherEvent.length==1
          if trainer[2].length<=3
            $PokemonTemp.waitingTrainer=[trainer,thisEvent.id,endspeech,doublebattle]
            return BR_LOSS # changed by SH
          end
        end
      end
      
      if $PokemonGlobal.partner && ($PokemonTemp.waitingTrainer || doublebattle)
        othertrainer=PokeBattle_Trainer.new(
          $PokemonGlobal.partner[1],$PokemonGlobal.partner[0])
        othertrainer.id=$PokemonGlobal.partner[2]
        othertrainer.party=$PokemonGlobal.partner[3]
        playerparty=[]
        for i in 0...$Trainer.party.length
          playerparty[i]=$Trainer.party[i]
        end
        for i in 0...othertrainer.party.length
          playerparty[6+i]=othertrainer.party[i]
        end
        fullparty1=true
        playertrainer=[$Trainer,othertrainer]
        doublebattle=true
      else
        playerparty=$Trainer.party
        playertrainer=$Trainer
        fullparty1=false
      end
      if $PokemonTemp.waitingTrainer
        combinedParty=[]
        fullparty2=false
        if false
          if $PokemonTemp.waitingTrainer[0][2].length>3
            raise _INTL("Opponent 1's party has more than three Pokémon, which is not allowed")
          end
          if trainer[2].length>3
            raise _INTL("Opponent 2's party has more than three Pokémon, which is not allowed")
          end
        elsif $PokemonTemp.waitingTrainer[0][2].length>3 || trainer[2].length>3
          for i in 0...$PokemonTemp.waitingTrainer[0][2].length
            combinedParty[i]=$PokemonTemp.waitingTrainer[0][2][i]
          end
          for i in 0...trainer[2].length
            combinedParty[6+i]=trainer[2][i]
          end
          fullparty2=true
        else
          for i in 0...$PokemonTemp.waitingTrainer[0][2].length
            combinedParty[i]=$PokemonTemp.waitingTrainer[0][2][i]
          end
          for i in 0...trainer[2].length
            combinedParty[3+i]=trainer[2][i]
          end
          fullparty2=false
        end
        #Sky battle eligibility for opponent
        if skybattle
          count=0
          for poke in combinedParty
            count+=1 if pbCanSkyBattle?(poke)
          end
          if count==0
            Kernel.pbMessage(_INTL("The opponents don't have any eligible pokemon for a sky battle"))
            return false
          end
        end
        scene=pbNewBattleScene
        battle=PokeBattle_Battle.new(scene,playerparty,combinedParty,playertrainer,
          [$PokemonTemp.waitingTrainer[0][0],trainer[0]],skybattle,inverse,gen)
        trainerbgm=pbGetTrainerBattleBGM(
          [$PokemonTemp.waitingTrainer[0][0],trainer[0]])
        battle.fullparty1=fullparty1
        battle.fullparty2=fullparty2
        battle.doublebattle=battle.pbDoubleBattleAllowed?()
        battle.endspeech=$PokemonTemp.waitingTrainer[2]
        battle.endspeech2=endspeech
        battle.items=[$PokemonTemp.waitingTrainer[0][1],trainer[1]]
      else
        #Sky battle eligibility for opponent
        if skybattle
          count=0
          for poke in trainer[2]
            count+=1 if pbCanSkyBattle?(poke)
          end
          if count==0
            Kernel.pbMessage(_INTL("The opponents don't have any eligible pokemon for a sky battle"))
            return false
          end
        end
        scene=pbNewBattleScene
        battle=PokeBattle_Battle.new(scene,playerparty,trainer[2],playertrainer,trainer[0],skybattle,inverse)
        battle.fullparty1=fullparty1
        battle.doublebattle=doublebattle ? battle.pbDoubleBattleAllowed?() : false
        battle.endspeech=endspeech
        battle.items=trainer[1]
        trainerbgm=pbGetTrainerBattleBGM(trainer[0])
      end
      if Input.press?(Input::CTRL) && $DEBUG
        Kernel.pbMessage(_INTL("SKIPPING BATTLE..."))
        Kernel.pbMessage(_INTL("AFTER LOSING..."))
        Kernel.pbMessage(battle.endspeech)
        Kernel.pbMessage(battle.endspeech2) if battle.endspeech2
        if $PokemonTemp.waitingTrainer
          pbMapInterpreter.pbSetSelfSwitch(
            $PokemonTemp.waitingTrainer[1],"A",true
          )
          $PokemonTemp.waitingTrainer=nil
        end
        return BR_WIN # changed by SH
      end
      Events.onStartBattle.trigger(nil,nil)
      battle.internalbattle=true
      pbPrepareBattle(battle)
      restorebgm=true
      decision=0
      pbBattleAnimation(trainerbgm,trainer[0].trainertype,trainer[0].name) { 
        pbSceneStandby {
            decision=battle.pbStartBattle(canlose)
        }
        if $PokemonGlobal.partner
          pbHealAll
          for i in $PokemonGlobal.partner[3]; i.heal; end
        end
        if decision==2 || decision==5
          if canlose
            for i in $Trainer.party; i.heal; end
            for i in 0...10
              Graphics.update
            end
          else
            $game_system.bgm_unpause
            $game_system.bgs_unpause
            Kernel.pbStartOver
          end
        else
          Events.onEndBattle.trigger(nil,decision)
          if decision==1
            if $PokemonTemp.waitingTrainer
              pbMapInterpreter.pbSetSelfSwitch(
                  $PokemonTemp.waitingTrainer[1],"A",true
              )
            end
          end
        end
      }
      Input.update
      $PokemonTemp.waitingTrainer=nil
      return decision  # changed by SH
    end
    Thanks, it works perfectly.
    And for anyone who has trouble with it, you have to show printable version.
    Also the sky battle and inverse battles are the next 2 places like so:

    "result = customTrainerBattle(trainer, "Oh no, you defeated me!",false,false,true,true)"
    --------------------------------------------------------------------------------------------------------------|.....|
    --------------------------------------------------------------------------------------------------------------^.....^
    -----------------------------------------------------------------------------------------------------------sky....inverse
     
    Back
    Top