• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
  • 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 Feature Question] Evolution method involving fainting in battle

  • 37
    Posts
    8
    Years
    • Seen Jan 21, 2021
    I'm trying to figure out how to script an evolution method for a Ghost type Eeveelution that would involve it fainting in battle as a prerequisite for evolving (may or may not need to level up before or after that same battle; whatever works script-wise honestly).

    In another topic (https://www.pokecommunity.com/threads/410401) a helpful user gave some suggestions for other methods, but this particular evolution method gave the following error whenever Eevee leveled up at all:

    Exception: NoMethodError

    Message: undefined method `fainted?' for #<PokeBattle_Pokemon:0xf37ff08>

    Pokemon_Evolution:896:in `pbMiniCheckEvolution'

    Pokemon_Evolution:999:in `pbCheckEvolution'

    Pokemon_Evolution:998:in `pbCheckEvolutionEx'

    Pokemon_Evolution:987:in `each'

    Pokemon_Evolution:987:in `pbCheckEvolutionEx'

    Pokemon_Evolution:998:in `pbCheckEvolution'

    PItem_Items:318:in `pbChangeLevel'

    PItem_ItemEffects:759

    PItem_ItemEffects:754:in `call'

    Event:150:in `trigger'

    -----

    Here was the script I used, under Evolution Methods)

    when PBEvolution::Fainted
    return poke if pokemon.level>=level && pokemon.fainted?

    The EVOPARAM was 1, and I'm using v16
    Any ideas how to script it properly? I'm flexible on the exact method, as long as it involves the Pokemon fainting in battle.
     
    Last edited:
    Since you're on v16, this might work for you: (broken link removed)
    This was written for v17.2, but I don't think that much changed in the battle system between v16 and v17.2 so it could still work. Also, make sure to read the entire thread, as I made replies to modify my original solution to fix some bugs.
     
    Thanks! From what you said it sounds like this method would also allow fainted Pokemon who evolve by leveling up or through an item to evolve too though? I'd like to route around that if possible. Is there a way to do it such that it evolves via level up when healthy, but only after having fainted at least once as a precondition? (ideally within the same battle, but not required I suppose)?
     
    Thanks! From what you said it sounds like this method would also allow fainted Pokemon who evolve by leveling up or through an item to evolve too though? I'd like to route around that if possible. Is there a way to do it such that it evolves via level up when healthy, but only after having fainted at least once as a precondition? (ideally within the same battle, but not required I suppose)?

    Ah, sorry about that, I didn't read your original post correctly the first time. The method I linked above indeed has nothing to do with leveling up at all - it solely checks for if a Pokemon fainted during battle or not.

    So, if I'm understanding your question, the way a Pokemon should evolve is by fainting in battle, getting revived, then leveling up to at least the minimum level? Or by leveling up first, THEN fainting? I think both are possible, but have slightly different approaches to coding them. Also, it definitely seems like a difficult way to evolve for the player, but I'm guessing that's your intention?
     
    Ah, sorry about that, I didn't read your original post correctly the first time. The method I linked above indeed has nothing to do with leveling up at all - it solely checks for if a Pokemon fainted during battle or not.

    So, if I'm understanding your question, the way a Pokemon should evolve is by fainting in battle, getting revived, then leveling up to at least the minimum level? Or by leveling up first, THEN fainting? I think both are possible, but have slightly different approaches to coding them. Also, it definitely seems like a difficult way to evolve for the player, but I'm guessing that's your intention?

    That was my original intention, yes (either of those would have worked ideally) but I'm actually fine with just the Pokemon fainting and then evolving after battle, it's just that I wouldn't want a universal edit that would then allow any Pokemon to evolve while fainted, which as I understood was a side-effect of the original solution you offered. So if you have any idea on how to avoid that side-effect (assuming it is), or a likely script for either of the two more complicated methods (faint -> lvl up or vice versa), I'd greatly appreciate it.
     
    That was my original intention, yes (either of those would have worked ideally) but I'm actually fine with just the Pokemon fainting and then evolving after battle, it's just that I wouldn't want a universal edit that would then allow any Pokemon to evolve while fainted, which as I understood was a side-effect of the original solution you offered. So if you have any idea on how to avoid that side-effect (assuming it is), or a likely script for either of the two more complicated methods (faint -> lvl up or vice versa), I'd greatly appreciate it.

    Alright, I think I can make it so that the Pokemon has to level up (to at least the minimum level), faint, AND be revived all in the same battle. To start, go to script section PField_Field, find "class PokemonTemp", and add this line below:
    Code:
    class PokemonTemp
      attr_accessor :encounterType 
      attr_accessor :evolutionLevels
      attr_accessor :faintedPokemon # ADD THIS LINE
    end

    Next, find the line "Events.onStartBattle+=proc {|sender,e|" and add the "faintedPokemon" array to the initialization like so:
    Code:
    Events.onStartBattle+=proc {|sender,e|
      $PokemonTemp.evolutionLevels=[]
      $PokemonTemp.faintedPokemon=[] # ADD THIS LINE
      for i in 0...$Trainer.party.length
        $PokemonTemp.evolutionLevels[i]=$Trainer.party[i].level
        $PokemonTemp.faintedPokemon[i] = false # ADD THIS LINE
      end
    }

    Then find the line "pbEvolutionCheck($PokemonTemp.evolutionLevels)" and this line underneath:
    Code:
    pbEvolutionCheck($PokemonTemp.evolutionLevels)
    $PokemonTemp.evolutionLevels=nil
    $PokemonTemp.faintedPokemon=nil # ADD THIS LINE

    What the previous code does is keep track of which Pokemon in the party have fainted in the current battle (which gets reset after every battle). Finally, in script section Pokemon_Evolution, under the function
    "def pbMiniCheckEvolution(pokemon,evonib,level,poke)", make your evolution check look like this:
    Code:
    when PBEvolution::Fainted
      return poke if pokemon.level>=level && $PokemonTemp.faintedPokemon[$Trainer.party.index(pokemon)]

    After this, when a Pokemon levels up to at least the minimum level and faints (doesn't matter which order), and is revived before the battle ends, it should evolve. Let me know if this works!
     
    What the previous code does is keep track of which Pokemon in the party have fainted in the current battle (which gets reset after every battle). Finally, in script section Pokemon_Evolution, under the function
    "def pbMiniCheckEvolution(pokemon,evonib,level,poke)", make your evolution check look like this:
    Code:
    when PBEvolution::Fainted
      return poke if pokemon.level>=level && $PokemonTemp.faintedPokemon[$Trainer.party.index(pokemon)]

    After this, when a Pokemon levels up to at least the minimum level and faints (doesn't matter which order), and is revived before the battle ends, it should evolve. Let me know if this works!

    Thanks so much for the detailed suggestions; unfortunately it's still not working (tried both orders). No error message after battle, just nothing happens. But when I use a Rare Candy on Eevee I get the following error:

    Exception: NoMethodError

    Message: undefined method `[]' for nil:NilClass

    Pokemon_Evolution:896:in `pbMiniCheckEvolution'

    Pokemon_Evolution:999:in `pbCheckEvolution'

    Pokemon_Evolution:998:in `pbCheckEvolutionEx'

    Pokemon_Evolution:987:in `each'

    Pokemon_Evolution:987:in `pbCheckEvolutionEx'

    Pokemon_Evolution:998:in `pbCheckEvolution'

    PItem_Items:318:in `pbChangeLevel'

    PItem_ItemEffects:759

    PItem_ItemEffects:754:in `call'

    Event:150:in `trigger'

    -------------------------

    Line 896 is the pbevolution method for Fainted that you provided. Interestingly, Eevee can level up during battle fine (whether it faints or not) and nothing happens afterward. And if it's poisoned and I use a Rare Candy, it evolves into the appropriate evolution I have tied to a different custom evolution.

    The lower sections of the error message correspond to this section primarily:

    # Checks whether a Pokemon can evolve now. If an item is used on the Pokémon,
    # checks whether the Pokemon can evolve with the given item.
    def pbCheckEvolution(pokemon,item=0)
    if item==0
    return pbCheckEvolutionEx(pokemon){|pokemon,evonib,level,poke|
    next pbMiniCheckEvolution(pokemon,evonib,level,poke)

    Any ideas? Haha. I'm guessing this is a particularly unusual evolution method. Is there a way to use the method you suggested to the person at Relic Castle but limit it to only certain Pokemon?
     
    Last edited:
    Thanks so much for the detailed suggestions; unfortunately it's still not working (tried both orders). No error message after battle, just nothing happens. But when I use a Rare Candy on Eevee I get the following error:

    Exception: NoMethodError

    Message: undefined method `[]' for nil:NilClass

    Pokemon_Evolution:896:in `pbMiniCheckEvolution'

    Pokemon_Evolution:999:in `pbCheckEvolution'

    Pokemon_Evolution:998:in `pbCheckEvolutionEx'

    Pokemon_Evolution:987:in `each'

    Pokemon_Evolution:987:in `pbCheckEvolutionEx'

    Pokemon_Evolution:998:in `pbCheckEvolution'

    PItem_Items:318:in `pbChangeLevel'

    PItem_ItemEffects:759

    PItem_ItemEffects:754:in `call'

    Event:150:in `trigger'

    -------------------------

    Line 896 is the pbevolution method for Fainted that you provided. Interestingly, Eevee can level up during battle fine (whether it faints or not) and nothing happens afterward. And if it's poisoned and I use a Rare Candy, it evolves into the appropriate evolution I have tied to a different custom evolution.

    The lower sections of the error message correspond to this section primarily:

    # Checks whether a Pokemon can evolve now. If an item is used on the Pokémon,
    # checks whether the Pokemon can evolve with the given item.
    def pbCheckEvolution(pokemon,item=0)
    if item==0
    return pbCheckEvolutionEx(pokemon){|pokemon,evonib,level,poke|
    next pbMiniCheckEvolution(pokemon,evonib,level,poke)

    Any ideas? Haha. I'm guessing this is a particularly unusual evolution method. Is there a way to use the method you suggested to the person at Relic Castle but limit it to only certain Pokemon?

    Oh man, I see I made two mistakes in my previous code. First off, change the evolution check in pbMiniCheckEvolution to this:
    Code:
    when PBEvolution::Fainted
      return poke if pokemon.level>=level && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pokemon)]

    Second, I forgot to include the code that will set a Pokemon's "faint flag" to true if it faints during battle. Go to script section PokeBattle_Battler, find the function "def pbFaint(showMessage=true)", and add the second line underneath the first line:
    Code:
    PBDebug.log("[Pokémon fainted] #{pbThis}") # Find this line
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true # Add this line below

    This should both fix the Rare Candy error you got and (hopefully) make the fainted evolution work for you. I'll look at the code again if it doesn't - I really doubt it's any more complicated than this.
     
    This should both fix the Rare Candy error you got and (hopefully) make the fainted evolution work for you. I'll look at the code again if it doesn't - I really doubt it's any more complicated than this.

    That fixed everything, thanks a ton; you've been really helpful. There's a few other semi-complicated custom scripting I'm planning to do but I'm thinking I can and should try implementing it myself. If I have a question though hopefully you don't mind if I ping you thanks to your knowledge here.

    Edit: Actually there is a minor one I seem to have run into a dead end on regarding starting off with a blooming (rather than fruiting) berry tree in the topic I made here, if you have any ideas: https://www.pokecommunity.com/threads/442316
     
    Last edited:
    That fixed everything, thanks a ton; you've been really helpful. There's a few other semi-complicated custom scripting I'm planning to do but I'm thinking I can and should try implementing it myself. If I have a question though hopefully you don't mind if I ping you thanks to your knowledge here.

    Edit: Actually there is a minor one I seem to have run into a dead end on regarding starting off with a blooming (rather than fruiting) berry tree in the topic I made here, if you have any ideas: https://www.pokecommunity.com/threads/442316

    Yeah np, glad it works now! I'll take a look at your berry tree problem too, though I can't think of what to do off the top of my head.
     
    Coming back from your other thread: https://www.pokecommunity.com/threads/442453, here's what your evolution handler should look like:
    Code:
     PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pkmn)]
      }
    })

    And as for the line "PokemonTemp.faintedPokemon[@pokemonIndex] = true", you can just put it under the PBDebug line in pbFaint like so:
    Code:
    PBDebug.log("[Pokémon fainted] #{pbThis} (#{@index})") if !showMessage # FIND THIS LINE
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true # ADD THIS LINE

    I assume you were able to do the steps involving setting up the $PokemonTemp.faintedPokemon array? If so then try that.
     
    Coming back from your other thread: https://www.pokecommunity.com/threads/442453, here's what your evolution handler should look like:
    Code:
     PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pkmn)]
      }
    })

    And as for the line "PokemonTemp.faintedPokemon[@pokemonIndex] = true", you can just put it under the PBDebug line in pbFaint like so:
    Code:
    PBDebug.log("[Pokémon fainted] #{pbThis} (#{@index})") if !showMessage # FIND THIS LINE
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true # ADD THIS LINE

    I assume you were able to do the steps involving setting up the $PokemonTemp.faintedPokemon array? If so then try that.


    Thanks, the Poisoned evolution works fine now, but I'm still getting this error whenever Eevee levels up (including after fainting) outside of a context it would evolve into another form in:

    Spoiler:


    I added in the "attr_accessor :faintedPokemon" line under the "class PokemonTemp" sections as before, and tried translating the other parts of the $PokemonTemp.faintedPokemon array like this:
    Code:
    Events.onStartBattle += proc { |_sender|
      # Record current levels of Pokémon in party, to see if they gain a level
      # during battle and may need to evolve afterwards
      $PokemonTemp.evolutionLevels = []
     [COLOR="Yellow"] $PokemonTemp.faintedPokemon = [][/COLOR]  [COLOR="Lime"]#Dusk&Dawn LevelFainted[/COLOR]
      for i in 0...$Trainer.party.length
        $PokemonTemp.evolutionLevels[i] = $Trainer.party[i].level
        [COLOR="Yellow"]$PokemonTemp.faintedPokemon[i] = false[/COLOR]  [COLOR="Lime"]#Dusk&Dawn LevelFainted[/COLOR]
      end
    Code:
    Events.onEndBattle += proc { |_sender,e|
      decision = e[0]
      canLose  = e[1]
      if NEWEST_BATTLE_MECHANICS || (decision!=2 && decision!=5)  
        if $PokemonTemp.evolutionLevels
          pbEvolutionCheck($PokemonTemp.evolutionLevels)
          $PokemonTemp.evolutionLevels = nil
          [COLOR="Yellow"]$PokemonTemp.faintedPokemon = nil[/COLOR] [COLOR="Lime"]#Dusk&Dawn LevelFainted[/COLOR]
        end
      end

    And I used the codes you suggested above for the evolution function and PBDebug of course. Any idea what the issue is?
     
    Thanks, the Poisoned evolution works fine now, but I'm still getting this error whenever Eevee levels up (including after fainting) outside of a context it would evolve into another form in:

    Spoiler:

    Hm... it looks like you've done everything right... and I'm not really sure why it's crashing. Can you show me what the lines around line 322 in Pokemon_Evolution look like? Maybe like lines 312-332 or so.
     
    Hm... it looks like you've done everything right... and I'm not really sure why it's crashing. Can you show me what the lines around line 322 in Pokemon_Evolution look like? Maybe like lines 312-332 or so.

    Sure; this is 312 - 332. Line 322 is underlined:
    Code:
    })
    
    PBEvolution.register(:LevelPoisoned, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.status==PBStatuses::POISON
      }
    }) #Dusk&Dawn
    
    PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        [U]next pkmn.level >= parameter && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pkmn)][/U]
      }
    }) #Dusk&Dawn
    
    PBEvolution.register(:LevelDay, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && PBDayNight.isDay?
      }
    })
    
    PBEvolution.register(:LevelNight, {
     
    Last edited:
    Sure; this is 312 - 332. Line 322 is underlined:
    Code:
    })
    
    PBEvolution.register(:LevelPoisoned, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.status==PBStatuses::POISON
      }
    }) #Dusk&Dawn
    
    PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        [U]next pkmn.level >= parameter && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pkmn)][/U]
      }
    }) #Dusk&Dawn
    
    PBEvolution.register(:LevelDay, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && PBDayNight.isDay?
      }
    })
    
    PBEvolution.register(:LevelNight, {

    Okay, this looks correct. I do realize I made a small mistake in pbFaint, though. Replace this line:
    Code:
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true
    with:
    Code:
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true if pbOwnedByPlayer?
    Otherwise even opposing Pokemon could trigger this value on some random Pokemon on your own team.

    I tested all this myself on a clean v18.1 project, and it seems to work for me. Are you sure you defined the constant "LevelFainted" correctly? And updated "self.maxValue" inside Pokemon_Evolution after adding all those evolution methods? And that your evolutions are defined correctly in the PBS? Those are the only things we didn't discuss in this thread, so maybe there's an issue there? And of course, double check that all the code we DID discuss are all in the right places and everything.
     
    I tested all this myself on a clean v18.1 project, and it seems to work for me. Are you sure you defined the constant "LevelFainted" correctly? And updated "self.maxValue" inside Pokemon_Evolution after adding all those evolution methods? And that your evolutions are defined correctly in the PBS? Those are the only things we didn't discuss in this thread, so maybe there's an issue there? And of course, double check that all the code we DID discuss are all in the right places and everything.

    Thanks so much again; got it working now. I think the issue was that I'd forgotten to add the ",1" in the PBS to give a minimum level.
     
    Oh man, I see I made two mistakes in my previous code. First off, change the evolution check in pbMiniCheckEvolution to this:
    Code:
    when PBEvolution::Fainted
      return poke if pokemon.level>=level && $PokemonTemp.faintedPokemon && $PokemonTemp.faintedPokemon[$Trainer.party.index(pokemon)]

    Second, I forgot to include the code that will set a Pokemon's "faint flag" to true if it faints during battle. Go to script section PokeBattle_Battler, find the function "def pbFaint(showMessage=true)", and add the second line underneath the first line:
    Code:
    PBDebug.log("[Pokémon fainted] #{pbThis}") # Find this line
    $PokemonTemp.faintedPokemon[@pokemonIndex] = true # Add this line below

    This should both fix the Rare Candy error you got and (hopefully) make the fainted evolution work for you. I'll look at the code again if it doesn't - I really doubt it's any more complicated than this.
    I've been trying to implement this evolution method in v21.1 but the essentials scripts appear to have changed dramatically, and I'm having trouble figuring out what this extra logic would correspond to now. I imagine a lot of this happens in [[Battler]], potentially using attr_reader :fainted, but I'm feeling quite lost. Any assistance in modernizing this would be greatly appreciated!
     
    Back
    Top