Pokemon-Style Types

Discussion in 'RGSS3 Script Requests' started by Vis_Mage, Feb 6, 2019.

  1. Vis_Mage

    Vis_Mage Novice Magician Veteran

    Messages:
    388
    Likes Received:
    141
    Location:
    Ridge Island
    First Language:
    English
    Primarily Uses:
    RMVXA
    Hello!

    I was hoping someone could help me create a script that can assign "Types" to enemies.

    To better explain, types are just the monster's defensive element. For example, all Flying type Pokemon are weak to electric, rock, and ice attacks, while resisting steel and fighting attacks, and additionally, are immune to ground attacks. While this is possible to set up with element rates for each monster, with several hundred monsters that I'm hoping to apply types to, I'm hoping this could greatly reduce the workload of setting them each up individually, as well as allow for future-proofing, in case I change any type weaknesses/resistances in the future.

    Pretty much what I'm hoping to have is an editable section in the script, set up something like this:

    1 => "Flying", [2,3,4], [5,6], [7]

    In which:
    1 is the element ID in the database
    "Flying" is the name of the element, used in a note tag below
    [2,3,4] are the weaknesses, that deal 200% damage
    [5,6] are the resistances, that deal 50% damage
    [7] are the immunities, that deal no damage

    Once that's set up, I'm hoping to have a note tag along the lines of <PKtype: Flying, Fire> to give an enemy, and give them their appointed weaknesses/resistances/immunities.

    There are some creatures that are duel type (such as the Flying and Fire example above). In such cases, those types' weaknesses/resistances/immunities would combine. For example, if they were both weak to Rock element attacks, then the damage would become 400%. Likewise, if they both resisted Steel attacks, they would only receive 25% damage. Lastly, imminities outweigh anything else, meaning if flying is immune to Ground attacks, but fire is weak to them, then the flying/fire monster is still immune.

    I didn't really realize how massive of a request this was until I sat down and typed it all out, I'm sorry if it's overwhelming. I hope this all makes some sense. By all means, let me know if you have any questions.

    Thank you! :kaohi:
     
    Last edited: Feb 7, 2019
    #1
  2. A-Moonless-Night

    A-Moonless-Night WINTER IS COMING Veteran

    Messages:
    505
    Likes Received:
    362
    Location:
    New Zealand
    First Language:
    English
    Primarily Uses:
    RMVXA
    I feel like I've probably forgotten something (and maybe I've overthought it), but give this a go:
    Code:
    =begin
    #==============================================================================#
    #   AMN Pokemon Element Groups
    #   Version 1.00
    #   Author: AMoonlessNight
    #   Date: 07 Feb 2019
    #   Latest: 07 Feb 2019
    #==============================================================================#
    #   UPDATE LOG
    #------------------------------------------------------------------------------#
    # 07 Feb 2019 - created the script
    #==============================================================================#
    #   TERMS OF USE
    #------------------------------------------------------------------------------#
    # - Please credit AMoonlessNight or A-Moonless-Night
    # - Free for non-commercial use
    # - Contact for commercial use
    # - I'd love to see your game if you end up using one of my scripts
    #==============================================================================#
    
    Requested by Vis_Mage
    
    This script makes it so that you can set up element groups, much like Pokemon,
    with specific weaknesses and resistances. You can then give these groups to
    enemies using a notetag (rather than setting up multiple element rates in the
    features section).
    
    Use the following in an enemy's notes:
    
    <PKtype: x, x>
    
    where x is the name of the element in the database
    
    =end
    module AMN_Poke_Types
      Types = {
    #==============================================================================
    # ** EDITABLE REGION BELOW
    #------------------------------------------------------------------------------
    #  Change the values in the area below to suit your needs.
    #==============================================================================
    
    
    # Element ID => {:weak => [1,2,3], :resist => [4,5], :immune => [6]
      1 => {:weak => [4], :resist => [3, 2], :immune => [1],},
      2 => {:weak => [3], :resist => [1, 5], :immune => [2],},
      3 => {:weak => [2], :resist => [4, 5], :immune => [3],},
     
     
    #==============================================================================
    # ** END OF EDITABLE REGION
    #------------------------------------------------------------------------------
    #  Please do not edit below this point unless you know what you are doing.
    #==============================================================================
    
      } # <-- this carries the weight of the universe
     
      Regex = /<PKtype:*\s+(.+)>/i
    
    end
    
    module DataManager
      class << self
        alias :amn_poketypes_datamanager_loadnormaldb :load_normal_database
        alias :amn_poketypes_datamanager_loadbattletestdb :load_battle_test_database
      end
    
      def self.load_normal_database
        amn_poketypes_datamanager_loadnormaldb
        set_up_poke_elements
      end
    
      def self.load_battle_test_database
        amn_poketypes_datamanager_loadbattletestdb
        set_up_poke_elements
      end
     
      def self.set_up_poke_elements
        $game_poke_elements = {}
        $data_system.elements.each_with_index do |ele, id|
          weak, resist, immune = [[]] * 3
          if AMN_Poke_Types::Types.key?(id)
            weak = AMN_Poke_Types::Types[id][:weak]
            resist = AMN_Poke_Types::Types[id][:resist]
            immune = AMN_Poke_Types::Types[id][:immune]
          end
          $game_poke_elements[id] = Game_PokeElement.new(weak, resist, immune)
        end
      end
     
    end
    
    Game_PokeElement = Struct.new(:weak, :resist, :immune)
    
    class Game_BattlerBase
      WEAKNESS_RATE  = 2.0
      RESIST_RATE    = 0.5
      IMMUNE_RATE    = 0.0
    
      def setup_poke_types
        @poke_types = []
      end
     
      def poke_types
        @poke_types
      end
     
    end
    
    class Game_Enemy < Game_Battler
     
      alias amn_poketypes_gameenemy_init  initialize
      def initialize(*args)
        amn_poketypes_gameenemy_init(*args)
        setup_poke_types
      end
     
      def element_rate(element_id)
        return IMMUNE_RATE if @poke_types.any? { |i| $game_poke_elements[i].immune.include?(element_id) }
        a = @poke_types.inject(1.0) {|r, ft| r *= RESIST_RATE if $game_poke_elements[ft].resist.include?(element_id) }
        b = @poke_types.inject(1.0) {|r, ft| r *= WEAKNESS_RATE if $game_poke_elements[ft].weak.include?(element_id) }
        a && b ? a * b : super
      end
     
      def setup_poke_types
        super
        enemy.note.scan(AMN_Poke_Types::Regex).flatten.each do |res|
          res.split(',').each { |type| @poke_types << $data_system.elements.index(type.strip)}
        end
        @poke_types.flatten.compact!
      end
     
    end
    I also haven't really tested it much, sorry.
     
    #2
    Vis_Mage likes this.
  3. Vis_Mage

    Vis_Mage Novice Magician Veteran

    Messages:
    388
    Likes Received:
    141
    Location:
    Ridge Island
    First Language:
    English
    Primarily Uses:
    RMVXA
    Thanks a ton! :kaothx:

    I did a bit of testing, and seem to have ran into a couple bugs. When hitting an enemy with an element they're weak to, I get the following crash:
    Code:
    Pokemon Types: 142:in 'block in element_rate': undefined method '*' for nil:NilClass, NoMethodError
    And here's that line in the script
    Code:
        b = @poke_types.inject(1.0) {|r, ft| r *= WEAKNESS_RATE if $game_poke_elements[ft].weak.include?(element_id) }
    Interestingly enough, hitting an enemy with an element they resist doesn't cause a crash, but doesn't appear to change the damage (dealt 100 damage regardless of if they resisted, or were neutral).

    On the bright side though, immunities seem to work just fine!
     
    #3
  4. A-Moonless-Night

    A-Moonless-Night WINTER IS COMING Veteran

    Messages:
    505
    Likes Received:
    362
    Location:
    New Zealand
    First Language:
    English
    Primarily Uses:
    RMVXA
    Oops, yep. This should work better:
    Code:
    =begin
    #==============================================================================#
    #   AMN Pokemon Element Groups
    #   Version 1.00
    #   Author: AMoonlessNight
    #   Date: 07 Feb 2019
    #   Latest: 08 Feb 2019
    #==============================================================================#
    #   UPDATE LOG
    #------------------------------------------------------------------------------#
    # 07 Feb 2019 - created the script
    # 08 Feb 2019 - fixed error with calculating resistances/weaknesses
    #==============================================================================#
    #   TERMS OF USE
    #------------------------------------------------------------------------------#
    # - Please credit AMoonlessNight or A-Moonless-Night
    # - Free for non-commercial use
    # - Contact for commercial use
    # - I'd love to see your game if you end up using one of my scripts
    #==============================================================================#
    
    Requested by Vis_Mage
    
    This script makes it so that you can set up element groups, much like Pokemon,
    with specific weaknesses and resistances. You can then give these groups to
    enemies using a notetag (rather than setting up multiple element rates in the
    features section).
    
    Use the following in an enemy's notes:
    
    <PKtype: x, x>
    
    where x is the name of the element in the database
    
    =end
    module AMN_Poke_Types
      Types = {
    #==============================================================================
    # ** EDITABLE REGION BELOW
    #------------------------------------------------------------------------------
    #  Change the values in the area below to suit your needs.
    #==============================================================================
    
    
    # Element ID => {:weak => [1,2,3], :resist => [4,5], :immune => [6]
      1 => {:weak => [4], :resist => [3, 2], :immune => [1],},
      2 => {:weak => [3], :resist => [1, 5], :immune => [2],},
      3 => {:weak => [2], :resist => [3, 5], :immune => [4],},
     
     
    #==============================================================================
    # ** END OF EDITABLE REGION
    #------------------------------------------------------------------------------
    #  Please do not edit below this point unless you know what you are doing.
    #==============================================================================
    
      } # <-- this carries the weight of the universe
     
      Regex = /<PKtype:*\s+(.+)>/i
    
    end
    
    module DataManager
      class << self
        alias :amn_poketypes_datamanager_loadnormaldb :load_normal_database
        alias :amn_poketypes_datamanager_loadbattletestdb :load_battle_test_database
      end
    
      def self.load_normal_database
        amn_poketypes_datamanager_loadnormaldb
        set_up_poke_elements
      end
    
      def self.load_battle_test_database
        amn_poketypes_datamanager_loadbattletestdb
        set_up_poke_elements
      end
     
      def self.set_up_poke_elements
        $game_poke_elements = {}
        $data_system.elements.each_with_index do |ele, id|
          weak, resist, immune = [[]] * 3
          if AMN_Poke_Types::Types.key?(id)
            weak = AMN_Poke_Types::Types[id][:weak]
            resist = AMN_Poke_Types::Types[id][:resist]
            immune = AMN_Poke_Types::Types[id][:immune]
          end
          $game_poke_elements[id] = Game_PokeElement.new(id, weak, resist, immune)
        end
      end
     
    end
    
    Game_PokeElement = Struct.new(:id, :weak, :resist, :immune)
    
    class Game_BattlerBase
      WEAKNESS_RATE  = 2.0
      RESIST_RATE    = 0.5
      IMMUNE_RATE    = 0.0
    
      def setup_poke_types
        @poke_types = []
      end
     
      def poke_types
        @poke_types
      end
     
    end
    
    class Game_Enemy < Game_Battler
     
      alias amn_poketypes_gameenemy_init  initialize
      def initialize(*args)
        amn_poketypes_gameenemy_init(*args)
        setup_poke_types
      end
     
      def element_rate(element_id)
        return IMMUNE_RATE if @poke_types.any? { |e| e.immune.include?(element_id) }
        return super if @poke_types.empty?
        result = get_element_resistance(element_id)
        result *= get_element_weakness(element_id)
        result
      end
     
      def get_element_weakness(element_id)
        res = @poke_types.select { |e| e.weak.include?(element_id) }
        return 1.0 if res.empty?
        res.inject(1.0) {|r,i| r *= WEAKNESS_RATE}
      end
     
      def get_element_resistance(element_id)
        res = @poke_types.select { |e| e.resist.include?(element_id) }
        return 1.0 if res.empty?
        res.inject(1.0) {|r,i| r *= RESIST_RATE}
      end
     
      def setup_poke_types
        super
        ele = []
        enemy.note.scan(AMN_Poke_Types::Regex).flatten.each do |res|
          res.split(',').each { |type| ele << $data_system.elements.index(type.strip)}
        end
        @poke_types = ele.flatten.compact.collect { |i| $game_poke_elements[i] }
      end
     
    end
     
    #4
    Vis_Mage likes this.
  5. Vis_Mage

    Vis_Mage Novice Magician Veteran

    Messages:
    388
    Likes Received:
    141
    Location:
    Ridge Island
    First Language:
    English
    Primarily Uses:
    RMVXA
    You're a lifesaver! :kaopride:

    Everything seems to be working great, thank you!
     
    #5
    A-Moonless-Night likes this.

Share This Page