• 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 Trading Card Game 2 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.

[Scripting Question] Help with custom abilities

  • 4
    Posts
    2
    Years
    • Seen Nov 17, 2022
    Hello everyone, I'm having some issues with implementing a few custom abilities- four to be exact.
    I'm more familiar with python than I am with C++, so I'm probably missing some obvious quick fixes to actually get these to work correctly.
    However, after fiddling and comparing them with other similar abilities I'm rather kind of stumped.

    I'm working on four abilities,

    one of them being called Purity.
    The idea behind the ability is to give the user immunity against both poison and steel types, and when hit by said types moves summons Misty Terrain.
    The ability works, unfortunately only for the first type (in this case, poison)
    Code:
    Battle::AbilityEffects::MoveImmunity.add(:PURITY,
      proc { |ability, user, target, move, type, battle, show_message|
          next false if type !=:POISON || if type !=:STEEL
             
            if show_message
              battle.pbDisplay(_INTL("{1} absorbs the moves because of it's {2}!", target.pbThis, target.abilityName))
              battle.pbShowAbilitySplash(target)
              
              if Battle::Scene::USE_ABILITY_SPLASH
                battle.pbDisplay(_INTL("{1} purified the surrounding environment!", target.pbThis(true)))
                battle.pbStartTerrain(target, :Misty)
                
              else
                battle.pbDisplay(_INTL("It doesn't affect {1}...", target.pbThis(true)))
              end
              
              battle.pbHideAbilitySplash(target)
            end
          end
          next true
            
      }
    )


    The second ability is supposed to have a 50% 50% split on either setting up Misty Terrain or poisoning the opponent upon switch-in.
    Misty Terrain works 100% of the time ( i've referenced Effect Spores code for the random percent chance )
    Code:
    Battle::AbilityEffects::OnSwitchIn.add(:MIASMA,
      proc { |ability, user, target, battle, switch_in|
      #next false if target.asleep? || target.frozen?
      
      
      r = battle.pbRandom(2)
      next if r == 1 && user.poisoned?
      battle.pbShowAbilitySplash(target)
        
      battle.pbDisplay(_INTL("{1} releases a mysterious mist into the air!",target.pbThis))
      battle.pbHideAbilitySplash(target)
      
       case r
       when 0
         #sets up Misty Terrain
          battle.pbShowAbilitySplash(target)
          battle.pbStartTerrain(target, :Misty)
            
        when 1
          #Poison target
          if user.pbCanPoison?(target, Battle::Scene::USE_ABILITY_SPLASH)
            msg = nil
              if !Battle::Scene::USE_ABILITY_SPLASH
                  msg = _INTL("{1}'s {2} poisoned {3}!", target.pbThis,
                    target.abilityName, user.pbThis(true))
              end
                     
          end
            user.pbPoison(target, msg)
      end       
      }
    )

    The third ability is supposed to prevent the opponent from using any sort of berries, and if they have a berry as their held item, it damages them at the end of each turn. My issue with this ability is trying to check the opponent's held item and to see if they are holding a berry.
    The code is a complete mess so I would rather not show that.


    The last ability I haven't actually attempted yet.

    This one is supposed to prevent the opponent from using any berries as well, instead this time if the opponent is holding a berry, I want the user of this ability to be able to use the berry when needed ( like using the opponent Sitrus berry when low health, or using the chest berry when asleep), without taking the berry as there own held item.

    Not entirely sure if that can be done without replacing the user-held item permanently. I think switching the users and the opponents held items temporarily, using the berry, then taking back their previous item should be able to work?? however, I haven't been able to attempt that yet.
     
    When working with OR statements (the '||'), you shouldn't start that second statement with if, the syntax doesn't work that way

    instead, I suggest you use the following line in its place
    Code:
    next false if type !=:POISON || type !=:STEEL

    This skips the next segment if the type doesnt match Poison or Steel.

    On the second ability, I's suggest this:
    Code:
    Battle::AbilityEffects::OnSwitchIn.add(:MIASMA,
      proc { |ability, user, target, battle, switch_in|
    
      #Show ability splash, to announce the coming of an effect
      battle.pbShowAbilitySplash(target)  
      battle.pbDisplay(_INTL("{1} releases a mysterious mist into the air!",target.pbThis))
      battle.pbHideAbilitySplash(target)
      
      #Get a random number and do the switch case
      case rand(2)
      when 0
         #sets up Misty Terrain
         battle.pbShowAbilitySplash(target)
         battle.pbStartTerrain(target, :Misty)
       when 1
         #Poison target
         if r == 1 && user.poisoned? #Fail if target is already poisoned
           #Show fail message, or set up misty terrain instead??
         end
         if user.pbCanPoison?(target, Battle::Scene::USE_ABILITY_SPLASH)
           msg = nil
             if !Battle::Scene::USE_ABILITY_SPLASH
                 msg = _INTL("{1}'s {2} poisoned {3}!", target.pbThis,
                   target.abilityName, user.pbThis(true))
             end   
             user.pbPoison(target, msg) #Poison only if able
         end
      end       
      }
    )

    I haven't tested them, but they should probably work
     
    I'm assuming you are using Essentials v20.

    For "Purity", there are two errors in the first check:
    Code:
          next false if type !=:POISON || if type !=:STEEL
    it should be:
    Code:
          next false if type !=:POISON && type !=:STEEL
    The two errors were:
    • The condition should be "if bla bla", with only one "if", otherwise I don't know what it does and I'm surprised the game even starts ^^"
    • What you want is this ability to trigger when the type is either Poison or Steel. Thus, you don't want this ability to trigger if the type neither Poison nor Steel. Thus you quit the ability if the type is different to Poison and different to Steel. (This is called De Morgan's laws)

    Your ability "Miasma" doesn't have the right signature. All abilities that are "Battle::AbilityEffects::OnSwitchIn" should have this signature:
    Code:
    Battle::AbilityEffects::OnSwitchIn.add(:MIASMA,
      proc { |ability, battler, battle, switch_in|
    then replace all instances of "target" and "user" with "battler".

    Assuming you've done that, this line:
    Code:
      next if r == 1 && battler.poisoned?
    stops the ability if the holder of the ability is already poisoned; you should remove it.

    The part with Misty Terrain is ok, but the part with the poisoning, you need to choose a random Pokémon to poison, as the "target" is not part of the signature of the ability.
    Also, even if it is counter-intuitive, when you write "pikachu.pbPoison(charizard)", it means that Charizard will poison Pikachu (the way you wrote it suggests that you understand it the other way around). Same for "pikachu.pbCanPoison(charizard)".
    I suggest something like this:
    Code:
    Battle::AbilityEffects::OnSwitchIn.add(:MIASMA,
      proc { |ability, battler, battle, switch_in|
      
      r = battle.pbRandom(2)
      
      battle.pbShowAbilitySplash(battler)
      battle.pbDisplay(_INTL("{1} releases a mysterious mist into the air!",battler.pbThis))
      battle.pbHideAbilitySplash(battler)
      
      case r
      when 0
        #sets up Misty Terrain
        battle.pbShowAbilitySplash(battler)
        battle.pbStartTerrain(battler, :Misty)
    
      else # when 1
        # Direct opponent of the battler
        target = battler.pbDirectOpposing(true)
    
        # Poison target
        if target.pbCanPoison?(battler, Battle::Scene::USE_ABILITY_SPLASH)
          msg = nil
          if !Battle::Scene::USE_ABILITY_SPLASH
            msg = _INTL("{1}'s {2} poisoned {3}!", battler.pbThis,
              battler.abilityName, target.pbThis(true))
          end
          target.pbPoison(battler, msg)
        end
      end       
      }
    )

    For your third ability, I suggest you check how Unnerve works, because your ability is basically Unnerve + damage. You can check the ability of a Pokémon with this kind of code:
    Code:
    GameData::Item.get(battler.item).is_berry?

    Your fourth ability is very interesting, but I think you'll have to check a lot of code. I think you should include this code as an ability that is triggered every time a berry could be triggered.
    For example, Sitrus Berry is triggered when the holder takes damage. So, you will have to code the ability so that it triggers when your Pokémon takes damage, it checks the item of every opponent (don't forget that Pokémon battles are not always 1v1 I know that because I've coded up to 6v6 for my game lol) and if one has a Berry that can be used in this situation, your Pokémon will use it instead.
    But you have to do that for each situation which could trigger a berry, so it may end up in a lot of code.
     
    Back
    Top