• 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!
  • Dawn, Gloria, Juliana, or Summer - which Pokémon protagonist is your favorite? Let us know by voting in our poll!
  • 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] HM Replacements

  • 29
    Posts
    9
    Years
    • Seen Jan 5, 2024
    How I can do to make HM Replacements like break and moves rocks with any fighting or moves like Psychic, like on Pokémon Zeta/Insurgence? I really want that on my game!
     
    Last edited by a moderator:
    He was asking for HM Items, as he says it by name right there in the OP. But I can also give some tips for aliasing HM moves. The following code will allow you to alias the effects of HM moves when used from the Pokemon Menu.

    Code:
    # Add this above Main or somewhere else nice
    module HiddenMoveHandlers
      def self.addAlias(newitem,olditem)
        return if CanUseMove[olditem]==nil || UseMove[olditem]==nil
        CanUseMove.add(newitem, CanUseMove[olditem])
        UseMove.add(newitem, UseMove[olditem])
      end
    end
    
    # Use the following method to make Psychic act like Strength from the pokemon menu
    HiddenMoveHandlers.addAlias(:PSYCHIC, :STRENGTH)
    Now, as you can see from trying out the above example of Psychic using Strength's code, it's a bit hit and miss as to whether the dialog boxes will report the move correctly. Basically, if the move has its own method for displaying the text, chances are the name of the move is hardcoded, which is bad (in a few different ways, actually).

    Furthermore, this won't do anything for in-the-field use of the moves (ie, talking to a boulder). You'll have to edit the methods themselves to search for the expanded pool of moves:

    Code:
    def Kernel.pbStrength
      #...
      movefinder=Kernel.pbCheckMove(:STRENGTH)
      movefinder=Kernel.pbCheckMove(:PSYCHIC) if !movefinder  #Can't find strength user, find us a psychic user
      # [More here]
      if $DEBUG || movefinder
     
    break and moves rocks with any fighting or moves like Psychic, like on Pokémon Zeta/Insurgence? I really want that on my game!

    This is what his question was. He's after the system in Pokemon Insurgence, where most Fighting type moves break rocks (a la Rock Smash), and moves like Psychic can move rocks (a la Strength). It has nothing to do with the HM items.


    1.) In PSystem_Utilities, around line 2177, you should find this code:
    Code:
    # Checks whether any Pokémon in the party knows the given move, and returns
    # the index of that Pokémon, or nil if no Pokémon has that move.
    def pbCheckMove(move)
      move=getID(PBMoves,move)
      return nil if !move || move<=0
      for i in $Trainer.party
        next if i.isEgg?
        for j in i.moves
          return i if j.id==move
        end
      end
      return nil
    end

    Replace it with this:
    Code:
    # Checks whether any Pokémon in the party knows any of the given moves, and returns
    # the index of that Pokémon, or nil if no Pokémon has that move.
    def pbCheckMove(movelist)
      origsyntax=false
      if !movelist.is_a?(Array)
        movelist=[movelist]
        origsyntax=true
      end
      for i in 0...movelist.length
        if movelist[i].is_a?(Symbol) || movelist[i].is_a?(String)
          movelist[i]=getConst(PBMoves,movelist[i])
        end
      end
      movelist.compact!
      return nil if !movelist || movelist.length==0
      for i in $Trainer.party
        next if i.isEgg?
        for j in i.moves
          return i if movelist.include?(j.id) && origsyntax
          return [i,j] if movelist.include?(j.id)
        end
      end
      return nil
    end

    The game now allows you to check for a Pokemon in your party, not only that knows a particular move, but knows any of a particular set of moves.

    Now, to put this in action.

    2.) Go into PField_HiddenMoves, and Ctrl+F for "pbCheckMove". when there's an HM you want to replace with a list of moves, change it from pbCheckMove(:MOVENAME) to pbCheckMove([:MOVENAME1,:MOVENAME2,:MOVENAME3,etc])

    For example, line 433 reads:
    Code:
        movefinder=Kernel.pbCheckMove(:STRENGTH)
    Change it to:
    Code:
        movefound=Kernel.pbCheckMove([:STRENGTH,:BULLDOZE,:STEAMROLLER,:OMINOUSWIND,
                                      :ICYWIND,:GIGAIMPACT,:SLAM,:WHIRLWIND,:ROCKTHROW,
                                      :HEAVYSLAM,:BARRAGE,:PSYCHIC,:HEADBUTT])
        if movefound.is_a?(Array)
          movefinder=movefound[0]
          moveindex=movefound[1]
        else
          movefinder=movefound
        end
     
    Last edited:
    1.) In PSystem_Utilities, around line 2177, you should find this code:
    [snip]
    Replace it with this:
    Code:
      return nil if !move || move<=0

    That's going to throw an error without a move variable. I was just trying to write something like that, actually. I compacted the movelist array (to get rid of nils) and return nil if the array was empty. (Also, for the sake of saying the right move name, this method should be returning which move it finds. I did it by returning an array [pkmnIndex,moveId], and the coder can do something like

    Code:
    pkmn, move = pbCheckMove(:STRENGTH)
    to get the proper move being used. (I forget if you need a star in the above line or not.))
     
    Merge

    That's going to throw an error without a move variable. I was just trying to write something like that, actually. I compacted the movelist array (to get rid of nils) and return nil if the array was empty.
    Nice catch, I edited the relevant line of my initial post.


    (Also, for the sake of saying the right move name, this method should be returning which move it finds. I did it by returning an array [pkmnIndex,moveId], and the coder can do something like

    Code:
    pkmn, move = pbCheckMove(:STRENGTH)
    to get the proper move being used. (I forget if you need a star in the above line or not.))
    Also nice catch. I added a similar function to my own code. However, it only appears if the moves were inputted via an array as per the new syntax. If the code uses the old syntax with only one input, it'll only return the Pokemon index number, just so the TC doesn't have to change every instance of pbCheckMove.

    Just so you see it in action, TC, here's the new Strength:

    Code:
    #===============================================================================
    # Strength
    #===============================================================================
    def Kernel.pbStrength
      if $PokemonMap.strengthUsed
        Kernel.pbMessage(_INTL("Strength made it possible to move boulders around."))
      elsif $DEBUG ||
        (HIDDENMOVESCOUNTBADGES ? $Trainer.numbadges>=BADGEFORSTRENGTH : $Trainer.badges[BADGEFORSTRENGTH])
        [COLOR="Red"]movefound=Kernel.pbCheckMove([:STRENGTH,:BULLDOZE,:STEAMROLLER,:OMINOUSWIND,
                                      :ICYWIND,:GIGAIMPACT,:SLAM,:WHIRLWIND,:ROCKTHROW,
                                      :HEAVYSLAM,:BARRAGE,:PSYCHIC,:HEADBUTT])
        if movefound.is_a?(Array)
          movefinder=movefound[0]
          moveindex=movefound[1]
          movename=PBMoves.getName(movefinder.moves[moveindex].id)
        else
          movefinder=movefound
          movename="Strength"
        end[/COLOR]
        if $DEBUG || movefinder
          Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside."))
          if Kernel.pbConfirmMessage(_INTL("Would you like to use Strength?"))
            speciesname=!movefinder ? $Trainer.name : movefinder.name
            Kernel.pbMessage(_INTL("{1} used [COLOR="red"]{2}[/COLOR]!\1",speciesname[COLOR="red"],movename[/COLOR]))
            pbHiddenMoveAnimation(movefinder)
            Kernel.pbMessage(_INTL("{1}'s [COLOR="red"]{2}[/COLOR] made it possible to move boulders around!",speciesname[COLOR="Red"],movename[/COLOR]))
            $PokemonMap.strengthUsed=true
            return true
          end
        else
          Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside."))
        end
      else
        Kernel.pbMessage(_INTL("It's a big boulder, but a Pokémon may be able to push it aside."))
      end
      return false
    end
    
    Events.onAction+=proc{|sender,e|
       facingEvent=$game_player.pbFacingEvent
       if facingEvent
         if facingEvent.name=="Boulder"
           Kernel.pbStrength
           return
         end
       end
    }
    
    HiddenMoveHandlers::CanUseMove.add(:STRENGTH,proc{|move,pkmn|
       if !$DEBUG &&
          !(HIDDENMOVESCOUNTBADGES ? $Trainer.numbadges>=BADGEFORSTRENGTH : $Trainer.badges[BADGEFORSTRENGTH])
         Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
         return false
       end
       if $PokemonMap.strengthUsed
         Kernel.pbMessage(_INTL("Strength is already being used."))
         return false
       end
       return true  
    })
    
    HiddenMoveHandlers::UseMove.add(:STRENGTH,proc{|move,pokemon|
       pbHiddenMoveAnimation(pokemon)
       Kernel.pbMessage(_INTL("{1} used {2}!\1",pokemon.name,PBMoves.getName(move)))
       Kernel.pbMessage(_INTL("{1}'s [COLOR="red"]{2}[/COLOR] made it possible to move boulders around!",pokemon.name[COLOR="red"],PBMoves.getName(move)[/COLOR]))
       $PokemonMap.strengthUsed=true
       return true  
    })
     
    Last edited by a moderator:
    Spoiler:

    Thanks I'll try!


    Edit: I got this error :(

    ---------------------------
    Pokemon Supreme
    ---------------------------
    Exception: TypeError

    Message: cannot convert PBMove into Integer

    PField_HiddenMoves:439:in `[]'

    PField_HiddenMoves:439:in `pbStrength'

    PField_HiddenMoves:467

    PField_HiddenMoves:463:in `call'

    Event:54:in `trigger'

    Event:49:in `each'

    Event:49:in `trigger'

    Scene_Map:175:in `update'

    Scene_Map:68:in `main'

    Scene_Map:65:in `loop'



    This exception was logged in

    C:\Users\Jol the Hedgehog\Saved Games/Pokemon Supreme/errorlog.txt.

    Press Ctrl+C to copy this message to the clipboard.
    ---------------------------
    OK
    ---------------------------
     
    Last edited by a moderator:
    Back
    Top