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

[Scripting Question] Adding Dual-type moves in v16

  • 37
    Posts
    8
    Years
    • Seen Jan 21, 2021
    Trying to implement dual-type moves that work just like Flying Press into v16 but the secondary type (indicated in the script, coincidentally also Flying) doesn't seem to be having any effect in battle. I modeled the script on the Flying Press script in v17, as in contrast to v18 afaik there's no major differences in the script language for battles, but I'm thinking there's some difference I'm missing. This is what I have (it has a secondary effect that I don't believe should be influencing anything):

    ################################################################################
    # Bloody Talon - Dual type Dark+Flying move with chance to Flinch
    ################################################################################

    class PokeBattle_Move_162 < PokeBattle_Move
    def pbModifyDamage(damagemult,attacker,opponent)
    type=getConst(PBTypes,:FLYING) || -1
    if type>=0
    mult=PBTypes.getCombinedEffectiveness(type,
    opponent.type1,opponent.type2,opponent.effects[PBEffects::Type3])
    return ((damagemult*mult)/8).round
    end
    return damagemult
    end

    def pbAdditionalEffect(attacker,opponent)
    return if opponent.damagestate.substitute
    opponent.pbFlinch(attacker)
    end
    end

    The spacing isn't showing up here but should be accurate in the script (as an aside, how do you post proper spaced lines in a comment here?).
    Would appreciate any input.
     
    Last edited:
    Ah, v16 actually does differ from v17 slightly in that the method "PBTypes.getCombinedEffectiveness" does not take the pokemon's "third type" into account, so you have to do that manually. I actually have a copy of Flying Press from v16 which I can share here:
    Code:
    ################################################################################
    # Damage is multiplied by Flying's effectiveness against the target. Does double
    # damage and has perfect accuracy if the target is Minimized. (Flying Press)
    ################################################################################
    class PokeBattle_Move_144 < PokeBattle_Move
      def pbModifyDamage(damagemult,attacker,opponent)
        type=getConst(PBTypes,:FLYING) || -1
        if type>=0
          mult=PBTypes.getCombinedEffectiveness(type,opponent.type1,opponent.type2)
          if opponent.effects[PBEffects::Type3]>=0 &&
             opponent.effects[PBEffects::Type3]!=opponent.type1 &&
             opponent.effects[PBEffects::Type3]!=opponent.type2
            mult*=PBTypes.getEffectiveness(type,opponent.effects[PBEffects::Type3])
          else
            mult*=2
          end
          return ((damagemult*mult)/8).round
        end
        return damagemult
      end
    
      def tramplesMinimize?(param=1)
        return false if isConst?(@id,PBMoves,:MONSOON) #Monsoon does not trample
        return true if param==1 && USENEWBATTLEMECHANICS # Perfect accuracy
        return true if param==2 # Double damage
        return false
      end
    end
    Also, you can put code between "CODE" and "/CODE" tags to make them show up in code blocks (but with square brackets around them instead of quotation marks).
     
    Ah, v16 actually does differ from v17 slightly in that the method "PBTypes.getCombinedEffectiveness" does not take the pokemon's "third type" into account, so you have to do that manually. I actually have a copy of Flying Press from v16 which I can share here:
    Code:
    ################################################################################
    # Damage is multiplied by Flying's effectiveness against the target. Does double
    # damage and has perfect accuracy if the target is Minimized. (Flying Press)
    ################################################################################
    class PokeBattle_Move_144 < PokeBattle_Move
      def pbModifyDamage(damagemult,attacker,opponent)
        type=getConst(PBTypes,:FLYING) || -1
        if type>=0
          mult=PBTypes.getCombinedEffectiveness(type,opponent.type1,opponent.type2)
          if opponent.effects[PBEffects::Type3]>=0 &&
             opponent.effects[PBEffects::Type3]!=opponent.type1 &&
             opponent.effects[PBEffects::Type3]!=opponent.type2
            mult*=PBTypes.getEffectiveness(type,opponent.effects[PBEffects::Type3])
          else
            mult*=2
          end
          return ((damagemult*mult)/8).round
        end
        return damagemult
      end
    
      def tramplesMinimize?(param=1)
        return false if isConst?(@id,PBMoves,:MONSOON) #Monsoon does not trample
        return true if param==1 && USENEWBATTLEMECHANICS # Perfect accuracy
        return true if param==2 # Double damage
        return false
      end
    end
    Also, you can put code between "CODE" and "/CODE" tags to make them show up in code blocks (but with square brackets around them instead of quotation marks).

    Weird; still isn't doing anything different. It's not the case that the second type effectiveness is "invisible" in any sense right? The sound effect and message should convey the combined effectiveness? I tried making the main type Fighting to replicate the original further but still no difference, and I'm guessing you played with other combos as well based on the name Monsoon. Here's the code I used:

    Code:
     class PokeBattle_Move_162 < PokeBattle_Move
      def pbModifyDamage(damagemult,attacker,opponent)
        type=getConst(PBTypes,:FLYING) || -1
        if type>=0
          mult=PBTypes.getCombinedEffectiveness(type,opponent.type1,opponent.type2)
          if opponent.effects[PBEffects::Type3]>=0 &&
             opponent.effects[PBEffects::Type3]!=opponent.type1 &&
             opponent.effects[PBEffects::Type3]!=opponent.type2
            mult*=PBTypes.getEffectiveness(type,opponent.effects[PBEffects::Type3])
          else
            mult*=2
          end
          return ((damagemult*mult)/8).round
        end
        return damagemult
      end
    
      def pbAdditionalEffect(attacker,opponent)
        return if opponent.damagestate.substitute
        opponent.pbFlinch(attacker)
      end
    end

    Any other ideas? Thanks for continuing to help.

    I also keep debating whether I should try and upgrade the whole thing to v18, but I already had made quite a few script changes and am unsure of what significant benefits there would be for the work involved.
     
    Weird; still isn't doing anything different. It's not the case that the second type effectiveness is "invisible" in any sense right? The sound effect and message should convey the combined effectiveness? I tried making the main type Fighting to replicate the original further but still no difference, and I'm guessing you played with other combos as well based on the name Monsoon. Here's the code I used:

    Code:
     class PokeBattle_Move_162 < PokeBattle_Move
      def pbModifyDamage(damagemult,attacker,opponent)
        type=getConst(PBTypes,:FLYING) || -1
        if type>=0
          mult=PBTypes.getCombinedEffectiveness(type,opponent.type1,opponent.type2)
          if opponent.effects[PBEffects::Type3]>=0 &&
             opponent.effects[PBEffects::Type3]!=opponent.type1 &&
             opponent.effects[PBEffects::Type3]!=opponent.type2
            mult*=PBTypes.getEffectiveness(type,opponent.effects[PBEffects::Type3])
          else
            mult*=2
          end
          return ((damagemult*mult)/8).round
        end
        return damagemult
      end
    
      def pbAdditionalEffect(attacker,opponent)
        return if opponent.damagestate.substitute
        opponent.pbFlinch(attacker)
      end
    end

    Any other ideas? Thanks for continuing to help.

    I also keep debating whether I should try and upgrade the whole thing to v18, but I already had made quite a few script changes and am unsure of what significant benefits there would be for the work involved.

    You know what, I think Flying Press itself has a bug of not showing the correct effectiveness message. So it actually IS making a difference, but it's "invisible" as you said. I think this code would need to be placed (and reworked) under the function "def pbTypeModifier(type,attacker,opponent)" in script section PokeBattle_Move to get it to both do the correct type calculations AND show the correct message (see how the move Freeze-Dry makes type modifications here, though it's not quite the same effect). Also, this was apparently fixed in v18, but obviously you can't use the v18 version because of how different the battle system is.

    But honestly, I would recommend just upgrading to v18.1. The best I can summarize the benefits are a significantly easier battle system to work with and a whole lot of bug fixes, but that is not the full story. You can view the full changelog here: https://essentialsdocs.fandom.com/wiki/Change_log (sections v17, 17.1, 17.2, 18, and 18.1). Also, v16 is over 3 years outdated, so you're going to find less and less people able to help you, and fewer scripts will work for v16. Honestly, the only reason I'm able to help you now is because the project that I'm updating to v18 used to be on v16, so I still have a copy of that codebase, but I am just going to get rid of that eventually. There's even a tutorial to upgrading your game: https://essentialsdocs.fandom.com/wiki/Guide:How_to_upgrade_your_game, though you already know that updating the scripts are the most tedious part. I'm not going to say it's an easy process, but I think the end result will be rewarding, especially if your project isn't actually close to being released yet.
     
    I'm not going to say it's an easy process, but I think the end result will be rewarding, especially if your project isn't actually close to being released yet.

    Thanks for the advice; I'm most of the way through transferring everything to v18 including altered scripts, and fittingly enough the first real roadblock I've hit is coding the levelup while poisoned and levelup after fainting evolution methods you helped me with the latter of in v16 here: https://www.pokecommunity.com/threads/442225
    Another user years ago provided a working method for leveling up while poisoned in v16 here: https://www.pokecommunity.com/threads/410401

    This is the closest I've gotten:
    Code:
     PBEvolution.register(:LevelPoisoned, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.status!=PBStatuses::POISON
      }
    })

    I've been swapping various strings after the &&, including pkmn.poisoned? All except the one above (which did nothing) resulted in errors. How would I go about introducing a necessary status condition into evolution requirements? (I assume it can be added after the main parameter?)

    For evolving after fainting in the same battle I tried:
    Code:
     PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.fainted?
      }
    })

    How would I translate the working method you provided for v16 into the new scripting style? I know you also said I should add
    Code:
     $PokemonTemp.faintedPokemon[@pokemonIndex] = true
    into the def for pbFaint last time under
    Code:
     PBDebug.log("[Pokémon fainted] #{pbThis}")
    to set the faint flag during battle but the layout has a good deal more code in v18 here:
    Code:
      @battle.pbDisplayBrief(_INTL("{1} fainted!",pbThis)) if showMessage
        PBDebug.log("[Pokémon fainted] #{pbThis} (#{@index})") if !showMessage
        @battle.scene.pbFaintBattler(self)
        pbInitEffects(false)

    and the $PokemonTemp prefix isn't used anymore. If you could help here that would be amazing. On the positive side, the dual-type moves now work perfectly.
     
    Thanks for the advice; I'm most of the way through transferring everything to v18 including altered scripts, and fittingly enough the first real roadblock I've hit is coding the levelup while poisoned and levelup after fainting evolution methods you helped me with the latter of in v16 here: https://www.pokecommunity.com/threads/442225
    Another user years ago provided a working method for leveling up while poisoned in v16 here: https://www.pokecommunity.com/threads/410401

    This is the closest I've gotten:
    Code:
     PBEvolution.register(:LevelPoisoned, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.status!=PBStatuses::POISON
      }
    })

    I've been swapping various strings after the &&, including pkmn.poisoned? All except the one above (which did nothing) resulted in errors. How would I go about introducing a necessary status condition into evolution requirements? (I assume it can be added after the main parameter?)

    For evolving after fainting in the same battle I tried:
    Code:
     PBEvolution.register(:LevelFainted, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.fainted?
      }
    })

    How would I translate the working method you provided for v16 into the new scripting style? I know you also said I should add
    Code:
     $PokemonTemp.faintedPokemon[@pokemonIndex] = true
    into the def for pbFaint last time under
    Code:
     PBDebug.log("[Pokémon fainted] #{pbThis}")
    to set the faint flag during battle but the layout has a good deal more code in v18 here:
    Code:
      @battle.pbDisplayBrief(_INTL("{1} fainted!",pbThis)) if showMessage
        PBDebug.log("[Pokémon fainted] #{pbThis} (#{@index})") if !showMessage
        @battle.scene.pbFaintBattler(self)
        pbInitEffects(false)

    and the $PokemonTemp prefix isn't used anymore. If you could help here that would be amazing. On the positive side, the dual-type moves now work perfectly.

    Glad to see you on the v18 side! For your poison-level evolution method, change the "!=" to "==" like so:
    Code:
     PBEvolution.register(:LevelPoisoned, {
      "levelUpCheck" => proc { |pkmn, parameter|
        next pkmn.level >= parameter && pkmn.status==PBStatuses::POISON
      }
    })

    As for the fainting evolution, let me actually respond to that in your original thread: https://www.pokecommunity.com/threads/442225, just to keep it all together.
     
    Back
    Top