Pokemon-Style Types

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
574
Reaction score
196
First Language
English
Primarily Uses
RMMV
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:

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
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.
 

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
574
Reaction score
196
First Language
English
Primarily Uses
RMMV
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!
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
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
 

Vis_Mage

Novice Magician
Veteran
Joined
Jul 28, 2013
Messages
574
Reaction score
196
First Language
English
Primarily Uses
RMMV
You're a lifesaver! :kaopride:

Everything seems to be working great, thank you!
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:

Forum statistics

Threads
105,854
Messages
1,017,004
Members
137,562
Latest member
tamedeathman
Top