• 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.

[Scripting Question] Adding different forms to a Pokemon that already has one

155
Posts
10
Years
    • Seen Jun 11, 2021
    So I was trying to add Ancient Genesect to my game as the Genesect you get from a fossil. I tried to code it to where the drives that work with normal Genesect wouldn't work with the ancient Genesect, but the game crashed whenever I gave Ancient Genesect a drive.
    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) && pokemon.form!=5 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) && pokemon.form!=5
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) && pokemon.form!=5
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) && pokemon.form!=5
       if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 0
    }
    I have a feeling I'm doing something wrong, but I'm not sure what. Whenever I try giving it a drive with this code, I get this error:
    Code:
    Exception: SystemStackError
    
    Message: stack level too deep
    
    Pokemon_MultipleForms:1059
    
    Pokemon_MultipleForms:1055:in `call'
    
    Pokemon_MultipleForms:311:in `call'
    
    Pokemon_MultipleForms:6:in `form'
    
    Pokemon_MultipleForms:1059
    
    Pokemon_MultipleForms:1055:in `call'
    
    Pokemon_MultipleForms:311:in `call'
    
    Pokemon_MultipleForms:6:in `form'
    
    Pokemon_MultipleForms:1059
    
    Pokemon_MultipleForms:1055:in `call'
     
    Last edited:
    824
    Posts
    8
    Years
  • So I was trying to add Ancient Genesect to my game as the Genesect you get from a fossil. I tried to code it to where the drives that work with normal Genesect wouldn't work with the ancient Genesect, but the game crashed whenever I gave Ancient Genesect a drive.
    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) [B]&& pokemon.form!=5[/B]
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) [B]&& pokemon.form!=5[/B]
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) [B]&& pokemon.form!=5[/B]
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) [B]&& pokemon.form!=5[/B]
       if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 0
    }
    I have a feeling I'm doing something wrong, but I'm not sure what. Whenever I try giving it a drive with this code, I get this error:

    You are trying to call the form formula within a function that is called in the form formula, which creates an infinite loop.

    Unfortunately, I don't know how to do what you want to do, where you have both the Drive-based forms and a form that can't use Drives. Considering the fact that Genesect's canon forms don't have any actual strategic difference between them (Techno Blast looks at the Genesect's hold item, not its form. There's no difference to Genesect's base stats, ability, weight, or type when it has a Drive), maybe you could just remove the form change based on Drive? This does mean that the color of Modern Genesect's Drive won't visibly change, though.

    You'd also need to make sure that Techno Blast (effect code #09F in PokeBattle_MoveEffects, the bottom fourth of the code) doesn't change type if the user is an Ancient Genesect.
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    You are trying to call the form formula within a function that is called in the form formula, which creates an infinite loop.

    Unfortunately, I don't know how to do what you want to do, where you have both the Drive-based forms and a form that can't use Drives. Considering the fact that Genesect's canon forms don't have any actual strategic difference between them (Techno Blast looks at the Genesect's hold item, not its form. There's no difference to Genesect's base stats, ability, weight, or type when it has a Drive), maybe you could just remove the form change based on Drive? This does mean that the color of Modern Genesect's Drive won't visibly change, though.

    You'd also need to make sure that Techno Blast (effect code #09F in PokeBattle_MoveEffects, the bottom fourth of the code) doesn't change type if the user is an Ancient Genesect.
    Will this be a problem when trying to create a Mega Evolution for a Pokemon that has another form? Raichu for example. I have a few Alolan Forms coded into my game already as I anticipate Sun and Moon's release, but the way I have them coded is different from what you've done. I actually have them in as separate forms rather than your method, but I might have to resort to your method for this.

    Lets say I have an Alola Raichu holding Raichunite. How do I make sure its Mega Form is a different form from regular Mega Raichu?
     
    824
    Posts
    8
    Years
  • Will this be a problem when trying to create a Mega Evolution for a Pokemon that has another form? Raichu for example. I have a few Alolan Forms coded into my game already as I anticipate Sun and Moon's release, but the way I have them coded is different from what you've done. I actually have them in as separate forms rather than your method, but I might have to resort to your method for this.

    Lets say I have an Alola Raichu holding Raichunite. How do I make sure its Mega Form is a different form from regular Mega Raichu?

    getMegaForm isn't directly called in the form formula, so no. Making a Mega Evolution for a Pokemon that already has an alternate form will not cause an infinite loop.

    Just be sure that you do it like this:

    Code:
    "getMegaForm"=>proc{|pokemon|
       next 0 if pokemon.form==0
       # regular Castform has no Mega
       next 5 if isConst?(pokemon.item,PBItems,:CASTFORMITE) && pokemon.form%4==1
       # If Castform is in either form 1 or 5 (so that the remainder when dividing by 4 is 1),
       #     the Mega form is 5.
       next 6 if isConst?(pokemon.item,PBItems,:CASTFORMITE) && pokemon.form%4==2
       # If Castform is in either form 2 or 6 (so that the remainder when dividing by 4 is 2),
       #     the Mega form is 6.
       next 7 if isConst?(pokemon.item,PBItems,:CASTFORMITE) && pokemon.form%4==3
       # If Castform is in either form 3 or 7 (so that the remainder when dividing by 4 is 3),
       #     the Mega form is 7.
       next 8 if isConst?(pokemon.item,PBItems,:CASTFORMITE) && pokemon.form%4==0
       # If Castform is in either form 4 or 8 (so that the remainder when dividing by 4 is 0),
       #     the Mega form is 8.
       next
    },

    Because getMegaForm is called when the game checks if the Pokemon is Mega Evolved (to determine if it should show the rainbow Key Ring next to their name), so you want to be sure that the Mega Evolved form also says that it is the Mega.

    The counterpart to this is:
    Code:
    "getUnmegaForm"=>proc{|pokemon|
       next 0 if pokemon.form==0
       # regular Castform is its own non-Mega form
       next 4 if pokemon.form%4==0
       # make sure that form 4 stays non-Mega and that form 8 becomes form 4, not form 0
       next pokemon.form%4
       # otherwise, divide the form number by four and return the remainder
    },

    (except for the fact that Castform always reverts to normal Castform at the end of every battle, so "next 0" is actually enough.)
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    Not sure I did it right. I tried to condense the code a bit, but... Whenever the battle ends, Raichu becomes an Alolan Raichu.
    Code:
    MultipleForms.register(:RAICHU,{
    "getMegaForm"=>proc{|pokemon|
       next 2 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form==0
       next 3 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form==1
       next
    },
    "getUnmegaForm"=>proc{|pokemon|
       next 0 if pokemon.form==0
       next 1 if pokemon.form%2==0
       next pokemon.form%2
    },
    "getBaseStats"=>proc{|pokemon|
       next [60,100,115,100,110,110] if pokemon.form==2
       next [60,100,110,115,110,100] if pokemon.form==3
       next
    },
    "ability"=>proc{|pokemon|
       next getID(PBAbilities,:VOLTABSORB) if pokemon.form==2
       next getID(PBAbilities,:LEVITATE) if pokemon.form==3
       next
    },
    "onSetForm"=>proc{|pokemon,form|
       pbSeenForm(pokemon)
    }
    })
     
    824
    Posts
    8
    Years
  • Code:
    MultipleForms.register(:RAICHU,{
    "getMegaForm"=>proc{|pokemon|
       next 2 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form[COLOR="Red"]&2[/COLOR]==0
       next 3 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form[COLOR="Red"]&2[/COLOR]==1
       next
    },[COLOR="red"]
    "getUnmegaForm"=>proc{|pokemon|
       next pokemon.form%2
    },[/COLOR]
    "getBaseStats"=>proc{|pokemon|
       next [60,100,115,100,110,110] if pokemon.form==2
       next [60,100,110,115,110,100] if pokemon.form==3
       next
    },
    "ability"=>proc{|pokemon|
       next getID(PBAbilities,:VOLTABSORB) if pokemon.form==2
       next getID(PBAbilities,:LEVITATE) if pokemon.form==3
       next
    },
    "onSetForm"=>proc{|pokemon,form|
       pbSeenForm(pokemon)
    }
    })

    I may have made a mistake in using Castform as my example. You were copying lines that were Castform-specific. (Due to Castform's base form not having a Mega)

    For future reference:
    Spoiler:
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    That seems to fix the issue, but now I'm having another issue. Yes, Raichu's form now changes properly, but oddly enough, Alola Raichu refuses to change its typing or ability. The type remains the same as its default form as does its ability. However, both Mega Raichu and Mega Alola Raichu work perfectly. The only thing that changes on Alola Raichu is the sprite.
     
    824
    Posts
    8
    Years
  • Code:
    MultipleForms.register(:RAICHU,{
    "getMegaForm"=>proc{|pokemon|
       next 2 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form&2==0
       next 3 if isConst?(pokemon.item,PBItems,:RAICHUNITE) && pokemon.form&2==1
       next
    },
    "getUnmegaForm"=>proc{|pokemon|
       next pokemon.form%2
    },
    "getBaseStats"=>proc{|pokemon|
       next [60,100,115,100,110,110] if pokemon.form==2
       next [60,100,110,115,110,100] if pokemon.form==3
       next
    },[COLOR="Red"]
    "type2"=>proc{|pokemon|
       next getConst(PBTypes,:PSYCHIC) if pokemon.form%2==1
       next
    },
    "weight"=>proc{|pokemon|
       next 0.7 if pokemon.form%2==1
    },
    "height"=>proc{|pokemon|
       next 21.0 if pokemon.form%2==1
    },
    "ability"=>proc{|pokemon|
       next getID(PBAbilities,:SURGESURFER) if pokemon.form==1[/COLOR]
       next getID(PBAbilities,:VOLTABSORB) if pokemon.form==2
       next getID(PBAbilities,:LEVITATE) if pokemon.form==3
       next
    },
    "onSetForm"=>proc{|pokemon,form|
       pbSeenForm(pokemon)
    }
    })

    Need to include Alola Raichu's basic form in with the Mega Evolution code. Otherwise, the ME code overwrites the other code which you likely have in Pokemon_MultipleForms.
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    That fixed it! Thanks! If you ever find out how to get Genesect to work without removing the code for the drives' forms, please let me know.
     
    1,405
    Posts
    11
    Years
  • Why not just check for the map id for each Genesect form?

    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) && check that map doesn't include
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) &&  check that map doesn't include
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) && check that map doesn't' include
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) && check map doesn't include
       if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 0
    }

    I don't really know the code for that though sry xP. Also don't know if that is actually the solution.

    EDIT: Actually you are probably gonna need to put something on that specific Genesect that no other Genesect has so you can check for it(I'm guessing it will lose the Steel type in that form, so maybe for other forms check that it is Steel type?).
     
    Last edited:
    1,224
    Posts
    10
    Years
  • Often all that's needed is a rethinking of your logic

    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
        if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }
     
    1,405
    Posts
    11
    Years
  • Often all that's needed is a rethinking of your logic

    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
        if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }

    I was thinking about that, but wouldn't the forme just switch once you give it a drive?
     
    1,224
    Posts
    10
    Years
  • I was thinking about that, but wouldn't the forme just switch once you give it a drive?

    Nope, next will essentially return from the process in this case. If that were true, then no forms would ever work, since they all have "next 0" as the last option.
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    Often all that's needed is a rethinking of your logic

    Code:
    MultipleForms.register(:GENESECT,{
    "getForm"=>proc{|pokemon|
       maps=[79,84]
        if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }
    Thanks for your help. You and Quilva both. Genesect's form no longer changes out of the Ancient Form when he has the drives, but after testing it out, I've run into a few more issues. First of all, whenever I leave the map, Genesect changes back to its normal form. Second of all, any other Genesect that wasn't on the map upon being obtained automatically changes into the ancient form.

    I tried changing a line within PokeBattle_Battler to resolve this issue, but it still persists.
    Code:
    if isConst?(self.species,PBSpecies,:GENESECT) [B][COLOR=Red]&& self.form!=5[/COLOR][/B]
     
    Last edited:
    1,405
    Posts
    11
    Years
  • Thanks for your help. You and Quilva both. Genesect's form no longer changes out of the Ancient Form when he has the drives, but after testing it out, I've run into a few more issues. First of all, whenever I leave the map, Genesect changes back to its normal form. Second of all, any other Genesect that wasn't on the map upon being obtained automatically changes into the ancient form.

    I tried changing a line within PokeBattle_Battler to resolve this issue, but it still persists.
    Code:
    if isConst?(self.species,PBSpecies,:GENESECT) [B][COLOR=Red]&& self.form!=5[/COLOR][/B]

    Code:
    MultipleForms.register(:GENESECT,{
    "getFormOnCreation"=>proc{|pokemon|
       maps=[79,84]
        if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
    },
    "getForm"=>proc{|pokemon|
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }

    Something like this should work. No idea how getFormOnCreation and getForm interact though.
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    Code:
    MultipleForms.register(:GENESECT,{
    "getFormOnCreation"=>proc{|pokemon|
       maps=[79,84]
        if ($game_map && maps.include?($game_map.map_id))
         next 5
       end
    },
    "getForm"=>proc{|pokemon|
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }
    Something like this should work. No idea how getFormOnCreation and getForm interact though.
    Just tested it out. I can successfully bring a Regular Genesect into the map, but when giving myself the Genesect that's supposed to be ancient, it ends up being a normal Genesect as well.
     
    824
    Posts
    8
    Years
  • What about this?

    Code:
    "getForm"=>proc{|pokemon|
       maps=[79,84]
       next 5 if maps.include?(pokemon.obtainmap)
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }

    Now, rather than creating a form upon creation, the game forces the form of any Genesect that were created on those maps to be Ancient. It does this before it checks for Drives.
     
    155
    Posts
    10
    Years
    • Seen Jun 11, 2021
    What about this?

    Code:
    "getForm"=>proc{|pokemon|
       maps=[79,84]
       next 5 if maps.include?(pokemon.obtainmap)
       next 1 if isConst?(pokemon.item,PBItems,:SHOCKDRIVE) 
       next 2 if isConst?(pokemon.item,PBItems,:BURNDRIVE) 
       next 3 if isConst?(pokemon.item,PBItems,:CHILLDRIVE) 
       next 4 if isConst?(pokemon.item,PBItems,:DOUSEDRIVE) 
       next 0
    }
    Now, rather than creating a form upon creation, the game forces the form of any Genesect that were created on those maps to be Ancient. It does this before it checks for Drives.
    Just tried it out. Upon checking the summary, I got this:
    Code:
    Exception: NoMethodError
    
    Message: undefined method `obtainmap' for #<PokeBattle_Pokemon:0x90c7078>
    
    Pokemon_MultipleForms:1076
    
    Pokemon_MultipleForms:1074:in `call'
    
    Pokemon_MultipleForms:311:in `call'
    
    Pokemon_MultipleForms:6:in `form'
    
    Pokemon_MultipleForms:1084
    
    Pokemon_MultipleForms:1083:in `call'
    
    Pokemon_MultipleForms:311:in `call'
    
    Pokemon_MultipleForms:73:in `type2'
    
    PScreen_Summary:335:in `drawPageOne'
    
    PScreen_Summary:176:in `pbStartScene'
    EDIT: Nevermind. Turns out it was a case sensitive problem. I corrected it. Thanks for all your help!
     
    Last edited:
    Back
    Top