Removed all uses of ID numbers for types, Shape property in pokemon.txt must now be a name and not a number

This commit is contained in:
Maruno17
2021-06-16 20:32:30 +01:00
parent 0e8b1e70b1
commit 8c67127f06
15 changed files with 119 additions and 101 deletions

View File

@@ -8,6 +8,7 @@ module GameData
attr_reader :weaknesses attr_reader :weaknesses
attr_reader :resistances attr_reader :resistances
attr_reader :immunities attr_reader :immunities
attr_reader :icon_position # Where this type's icon is within types.png
DATA = {} DATA = {}
DATA_FILENAME = "types.dat" DATA_FILENAME = "types.dat"
@@ -19,29 +20,34 @@ module GameData
"IsSpecialType" => [4, "b"], "IsSpecialType" => [4, "b"],
"Weaknesses" => [5, "*s"], "Weaknesses" => [5, "*s"],
"Resistances" => [6, "*s"], "Resistances" => [6, "*s"],
"Immunities" => [7, "*s"] "Immunities" => [7, "*s"],
"IconPosition" => [8, "u"]
} }
extend ClassMethods extend ClassMethodsSymbols
include InstanceMethods include InstanceMethods
def self.each
DATA.each_value { |type| yield type }
end
def initialize(hash) def initialize(hash)
@id = hash[:id] @id = hash[:id]
@id_number = hash[:id_number] || -1 @real_name = hash[:name] || "Unnamed"
@real_name = hash[:name] || "Unnamed" @pseudo_type = hash[:pseudo_type] || false
@pseudo_type = hash[:pseudo_type] || false @special_type = hash[:special_type] || false
@special_type = hash[:special_type] || false @weaknesses = hash[:weaknesses] || []
@weaknesses = hash[:weaknesses] || [] @weaknesses = [@weaknesses] if !@weaknesses.is_a?(Array)
@weaknesses = [@weaknesses] if !@weaknesses.is_a?(Array) @resistances = hash[:resistances] || []
@resistances = hash[:resistances] || [] @resistances = [@resistances] if !@resistances.is_a?(Array)
@resistances = [@resistances] if !@resistances.is_a?(Array) @immunities = hash[:immunities] || []
@immunities = hash[:immunities] || [] @immunities = [@immunities] if !@immunities.is_a?(Array)
@immunities = [@immunities] if !@immunities.is_a?(Array) @icon_position = hash[:icon_position] || 0
end end
# @return [String] the translated name of this item # @return [String] the translated name of this item
def name def name
return pbGetMessage(MessageTypes::Types, @id_number) return pbGetMessageFromHash(MessageTypes::Types, @real_name)
end end
def physical?; return !@special_type; end def physical?; return !@special_type; end

View File

@@ -97,7 +97,7 @@ module GameData
"Height" => [0, "f"], "Height" => [0, "f"],
"Weight" => [0, "f"], "Weight" => [0, "f"],
"Color" => [0, "e", :BodyColor], "Color" => [0, "e", :BodyColor],
"Shape" => [0, "y", :BodyShape], "Shape" => [0, "e", :BodyShape],
"Habitat" => [0, "e", :Habitat], "Habitat" => [0, "e", :Habitat],
"Generation" => [0, "i"], "Generation" => [0, "i"],
"BattlerPlayerX" => [0, "i"], "BattlerPlayerX" => [0, "i"],

View File

@@ -262,8 +262,11 @@ def pbHiddenPower(pkmn)
iv = pkmn.iv iv = pkmn.iv
idxType = 0; power = 60 idxType = 0; power = 60
types = [] types = []
GameData::Type.each { |t| types.push(t.id) if !t.pseudo_type && ![:NORMAL, :SHADOW].include?(t.id)} GameData::Type.each do |t|
types.sort! { |a, b| GameData::Type.get(a).id_number <=> GameData::Type.get(b).id_number } types[t.icon_position] ||= []
types[t.icon_position].push(t.id) if !t.pseudo_type && ![:NORMAL, :SHADOW].include?(t.id)
end
types.flatten!.compact!
idxType |= (iv[:HP]&1) idxType |= (iv[:HP]&1)
idxType |= (iv[:ATTACK]&1)<<1 idxType |= (iv[:ATTACK]&1)<<1
idxType |= (iv[:DEFENSE]&1)<<2 idxType |= (iv[:DEFENSE]&1)<<2

View File

@@ -374,7 +374,7 @@ class FightMenuDisplay < BattleMenuBase
end end
@visibility["button_#{i}"] = true @visibility["button_#{i}"] = true
button.src_rect.x = (i==@index) ? @buttonBitmap.width/2 : 0 button.src_rect.x = (i==@index) ? @buttonBitmap.width/2 : 0
button.src_rect.y = GameData::Type.get(moves[i].type).id_number * BUTTON_HEIGHT button.src_rect.y = GameData::Type.get(moves[i].type).icon_position * BUTTON_HEIGHT
button.z = self.z + ((i==@index) ? 4 : 3) button.z = self.z + ((i==@index) ? 4 : 3)
end end
end end
@@ -400,7 +400,7 @@ class FightMenuDisplay < BattleMenuBase
end end
@visibility["typeIcon"] = true @visibility["typeIcon"] = true
# Type icon # Type icon
type_number = GameData::Type.get(move.type).id_number type_number = GameData::Type.get(move.type).icon_position
@typeIcon.src_rect.y = type_number * TYPE_ICON_HEIGHT @typeIcon.src_rect.y = type_number * TYPE_ICON_HEIGHT
# PP text # PP text
if move.total_pp>0 if move.total_pp>0

View File

@@ -463,14 +463,14 @@ class PokemonPokedex_Scene
textpos.push([(params[8]<0) ? "----" : @colorCommands[params[8]].name,444,116,2,base,shadow,1]) textpos.push([(params[8]<0) ? "----" : @colorCommands[params[8]].name,444,116,2,base,shadow,1])
# Draw type icons # Draw type icons
if params[2]>=0 if params[2]>=0
type_number = @typeCommands[params[2]].id_number type_number = @typeCommands[params[2]].icon_position
typerect = Rect.new(0,type_number*32,96,32) typerect = Rect.new(0,type_number*32,96,32)
overlay.blt(128,168,@typebitmap.bitmap,typerect) overlay.blt(128,168,@typebitmap.bitmap,typerect)
else else
textpos.push(["----",176,168,2,base,shadow,1]) textpos.push(["----",176,168,2,base,shadow,1])
end end
if params[3]>=0 if params[3]>=0
type_number = @typeCommands[params[3]].id_number type_number = @typeCommands[params[3]].icon_position
typerect = Rect.new(0,type_number*32,96,32) typerect = Rect.new(0,type_number*32,96,32)
overlay.blt(256,168,@typebitmap.bitmap,typerect) overlay.blt(256,168,@typebitmap.bitmap,typerect)
else else
@@ -562,7 +562,7 @@ class PokemonPokedex_Scene
if !sel[i] || sel[i]<0 if !sel[i] || sel[i]<0
textpos.push(["----",298+128*i,58,2,base,shadow,1]) textpos.push(["----",298+128*i,58,2,base,shadow,1])
else else
type_number = @typeCommands[sel[i]].id_number type_number = @typeCommands[sel[i]].icon_position
typerect = Rect.new(0,type_number*32,96,32) typerect = Rect.new(0,type_number*32,96,32)
overlay.blt(250+128*i,58,@typebitmap.bitmap,typerect) overlay.blt(250+128*i,58,@typebitmap.bitmap,typerect)
end end
@@ -665,7 +665,7 @@ class PokemonPokedex_Scene
when 2 # Type when 2 # Type
typerect = Rect.new(0,0,96,32) typerect = Rect.new(0,0,96,32)
for i in 0...cmds.length for i in 0...cmds.length
typerect.y = @typeCommands[i].id_number*32 typerect.y = @typeCommands[i].icon_position*32
overlay.blt(xstart+14+(i%cols)*xgap,ystart+6+(i/cols).floor*ygap,@typebitmap.bitmap,typerect) overlay.blt(xstart+14+(i%cols)*xgap,ystart+6+(i/cols).floor*ygap,@typebitmap.bitmap,typerect)
end end
textpos.push(["----", textpos.push(["----",
@@ -1012,7 +1012,6 @@ class PokemonPokedex_Scene
_INTL("Z")] _INTL("Z")]
@typeCommands = [] @typeCommands = []
GameData::Type.each { |t| @typeCommands.push(t) if !t.pseudo_type } GameData::Type.each { |t| @typeCommands.push(t) if !t.pseudo_type }
@typeCommands.sort! { |a, b| a.id_number <=> b.id_number }
@heightCommands = [1,2,3,4,5,6,7,8,9,10, @heightCommands = [1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20, 11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,30,35,40,45,50, 21,22,23,24,25,30,35,40,45,50,

View File

@@ -251,8 +251,8 @@ class PokemonPokedexInfo_Scene
# Draw the type icon(s) # Draw the type icon(s)
type1 = species_data.type1 type1 = species_data.type1
type2 = species_data.type2 type2 = species_data.type2
type1_number = GameData::Type.get(type1).id_number type1_number = GameData::Type.get(type1).icon_position
type2_number = GameData::Type.get(type2).id_number type2_number = GameData::Type.get(type2).icon_position
type1rect = Rect.new(0, type1_number * 32, 96, 32) type1rect = Rect.new(0, type1_number * 32, 96, 32)
type2rect = Rect.new(0, type2_number * 32, 96, 32) type2rect = Rect.new(0, type2_number * 32, 96, 32)
overlay.blt(296, 120, @typebitmap.bitmap, type1rect) overlay.blt(296, 120, @typebitmap.bitmap, type1rect)

View File

@@ -451,8 +451,8 @@ class PokemonSummary_Scene
# Draw all text # Draw all text
pbDrawTextPositions(overlay,textpos) pbDrawTextPositions(overlay,textpos)
# Draw Pokémon type(s) # Draw Pokémon type(s)
type1_number = GameData::Type.get(@pokemon.type1).id_number type1_number = GameData::Type.get(@pokemon.type1).icon_position
type2_number = GameData::Type.get(@pokemon.type2).id_number type2_number = GameData::Type.get(@pokemon.type2).icon_position
type1rect = Rect.new(0, type1_number * 28, 64, 28) type1rect = Rect.new(0, type1_number * 28, 64, 28)
type2rect = Rect.new(0, type2_number * 28, 64, 28) type2rect = Rect.new(0, type2_number * 28, 64, 28)
if @pokemon.type1==@pokemon.type2 if @pokemon.type1==@pokemon.type2
@@ -698,7 +698,7 @@ class PokemonSummary_Scene
for i in 0...Pokemon::MAX_MOVES for i in 0...Pokemon::MAX_MOVES
move=@pokemon.moves[i] move=@pokemon.moves[i]
if move if move
type_number = GameData::Type.get(move.type).id_number type_number = GameData::Type.get(move.type).icon_position
imagepos.push(["Graphics/Pictures/types", 248, yPos + 8, 0, type_number * 28, 64, 28]) imagepos.push(["Graphics/Pictures/types", 248, yPos + 8, 0, type_number * 28, 64, 28])
textpos.push([move.name,316,yPos,0,moveBase,moveShadow]) textpos.push([move.name,316,yPos,0,moveBase,moveShadow])
if move.total_pp>0 if move.total_pp>0
@@ -761,7 +761,7 @@ class PokemonSummary_Scene
yPos += 20 yPos += 20
end end
if move if move
type_number = GameData::Type.get(move.type).id_number type_number = GameData::Type.get(move.type).icon_position
imagepos.push(["Graphics/Pictures/types", 248, yPos + 8, 0, type_number * 28, 64, 28]) imagepos.push(["Graphics/Pictures/types", 248, yPos + 8, 0, type_number * 28, 64, 28])
textpos.push([move.name,316,yPos,0,moveBase,moveShadow]) textpos.push([move.name,316,yPos,0,moveBase,moveShadow])
if move.total_pp>0 if move.total_pp>0
@@ -783,8 +783,8 @@ class PokemonSummary_Scene
pbDrawTextPositions(overlay,textpos) pbDrawTextPositions(overlay,textpos)
pbDrawImagePositions(overlay,imagepos) pbDrawImagePositions(overlay,imagepos)
# Draw Pokémon's type icon(s) # Draw Pokémon's type icon(s)
type1_number = GameData::Type.get(@pokemon.type1).id_number type1_number = GameData::Type.get(@pokemon.type1).icon_position
type2_number = GameData::Type.get(@pokemon.type2).id_number type2_number = GameData::Type.get(@pokemon.type2).icon_position
type1rect = Rect.new(0, type1_number * 28, 64, 28) type1rect = Rect.new(0, type1_number * 28, 64, 28)
type2rect = Rect.new(0, type2_number * 28, 64, 28) type2rect = Rect.new(0, type2_number * 28, 64, 28)
if @pokemon.type1==@pokemon.type2 if @pokemon.type1==@pokemon.type2

View File

@@ -1437,8 +1437,8 @@ class PokemonStorageScene
imagepos.push(["Graphics/Pictures/shiny",156,198]) imagepos.push(["Graphics/Pictures/shiny",156,198])
end end
typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types")) typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
type1_number = GameData::Type.get(pokemon.type1).id_number type1_number = GameData::Type.get(pokemon.type1).icon_position
type2_number = GameData::Type.get(pokemon.type2).id_number type2_number = GameData::Type.get(pokemon.type2).icon_position
type1rect = Rect.new(0, type1_number * 28, 64, 28) type1rect = Rect.new(0, type1_number * 28, 64, 28)
type2rect = Rect.new(0, type2_number * 28, 64, 28) type2rect = Rect.new(0, type2_number * 28, 64, 28)
if pokemon.type1==pokemon.type2 if pokemon.type1==pokemon.type2

View File

@@ -52,8 +52,8 @@ class MoveRelearner_Scene
def pbDrawMoveList def pbDrawMoveList
overlay=@sprites["overlay"].bitmap overlay=@sprites["overlay"].bitmap
overlay.clear overlay.clear
type1_number = GameData::Type.get(@pokemon.type1).id_number type1_number = GameData::Type.get(@pokemon.type1).icon_position
type2_number = GameData::Type.get(@pokemon.type2).id_number type2_number = GameData::Type.get(@pokemon.type2).icon_position
type1rect=Rect.new(0, type1_number * 28, 64, 28) type1rect=Rect.new(0, type1_number * 28, 64, 28)
type2rect=Rect.new(0, type2_number * 28, 64, 28) type2rect=Rect.new(0, type2_number * 28, 64, 28)
if @pokemon.type1==@pokemon.type2 if @pokemon.type1==@pokemon.type2
@@ -71,7 +71,7 @@ class MoveRelearner_Scene
moveobject=@moves[@sprites["commands"].top_item+i] moveobject=@moves[@sprites["commands"].top_item+i]
if moveobject if moveobject
moveData=GameData::Move.get(moveobject) moveData=GameData::Move.get(moveobject)
type_number = GameData::Type.get(moveData.type).id_number type_number = GameData::Type.get(moveData.type).icon_position
imagepos.push(["Graphics/Pictures/types", 12, yPos + 8, 0, type_number * 28, 64, 28]) imagepos.push(["Graphics/Pictures/types", 12, yPos + 8, 0, type_number * 28, 64, 28])
textpos.push([moveData.name,80,yPos,0,Color.new(248,248,248),Color.new(0,0,0)]) textpos.push([moveData.name,80,yPos,0,Color.new(248,248,248),Color.new(0,0,0)])
if moveData.total_pp>0 if moveData.total_pp>0

View File

@@ -85,7 +85,7 @@ class TriadCard
end end
if type if type
typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types")) typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
type_number = GameData::Type.get(type).id_number type_number = GameData::Type.get(type).icon_position
typerect = Rect.new(0, type_number * 28, 64, 28) typerect = Rect.new(0, type_number * 28, 64, 28)
bitmap.blt(8, 50, typebitmap.bitmap, typerect, 192) bitmap.blt(8, 50, typebitmap.bitmap, typerect, 192)
typebitmap.dispose typebitmap.dispose
@@ -107,7 +107,7 @@ class TriadCard
# Draw card background # Draw card background
bitmap.blt(0, 0, cardbitmap.bitmap, Rect.new(0, 0, cardbitmap.width, cardbitmap.height)) bitmap.blt(0, 0, cardbitmap.bitmap, Rect.new(0, 0, cardbitmap.width, cardbitmap.height))
# Draw type icon # Draw type icon
type_number = GameData::Type.get(@type).id_number type_number = GameData::Type.get(@type).icon_position
typerect = Rect.new(0, type_number * 28, 64, 28) typerect = Rect.new(0, type_number * 28, 64, 28)
bitmap.blt(8, 50, typebitmap.bitmap, typerect, 192) bitmap.blt(8, 50, typebitmap.bitmap, typerect, 192)
# Draw Pokémon icon # Draw Pokémon icon

View File

@@ -182,7 +182,12 @@ end
# between numerical and alphabetical. # between numerical and alphabetical.
def pbChooseTypeList(default = nil) def pbChooseTypeList(default = nil)
commands = [] commands = []
GameData::Type.each { |t| commands.push([t.id_number, t.name, t.id]) if !t.pseudo_type } index = 0
GameData::Type.each do |t|
next if t.pseudo_type
commands.push([index, t.name, t.id])
index += 1
end
return pbChooseList(commands, default, nil, -1) return pbChooseList(commands, default, nil, -1)
end end

View File

@@ -128,7 +128,7 @@ module Compiler
yield lastsection,sectionname if havesection yield lastsection,sectionname if havesection
end end
# Used for types.txt, pokemon.txt, metadata.txt # Used for pokemon.txt, metadata.txt
def pbEachFileSection(f) def pbEachFileSection(f)
pbEachFileSectionEx(f) { |section,name| pbEachFileSectionEx(f) { |section,name|
yield section,name.to_i if block_given? && name[/^\d+$/] yield section,name.to_i if block_given? && name[/^\d+$/]
@@ -142,6 +142,13 @@ module Compiler
} }
end end
# Used for types.txt
def pbEachFileSection3(f)
pbEachFileSectionEx(f) { |section,name|
yield section,name if block_given? && name[/^.+$/]
}
end
# Used for phone.txt # Used for phone.txt
def pbEachSection(f) def pbEachSection(f)
lineno = 1 lineno = 1
@@ -600,6 +607,7 @@ module Compiler
# Parse string into a likely constant name and return its ID number (if any). # Parse string into a likely constant name and return its ID number (if any).
# Last ditch attempt to figure out whether a constant is defined. # Last ditch attempt to figure out whether a constant is defined.
#============================================================================= #=============================================================================
# Unused
def pbGetConst(mod,item,err) def pbGetConst(mod,item,err)
isDef = false isDef = false
begin begin
@@ -735,11 +743,12 @@ module Compiler
return if !$DEBUG return if !$DEBUG
begin begin
dataFiles = [ dataFiles = [
"abilities.dat",
"berry_plants.dat", "berry_plants.dat",
"encounters.dat", "encounters.dat",
"form2species.dat",
"items.dat", "items.dat",
"map_connections.dat", "map_connections.dat",
"map_metadata.dat",
"metadata.dat", "metadata.dat",
"moves.dat", "moves.dat",
"phone.dat", "phone.dat",
@@ -747,11 +756,6 @@ module Compiler
"ribbons.dat", "ribbons.dat",
"shadow_movesets.dat", "shadow_movesets.dat",
"species.dat", "species.dat",
"species_eggmoves.dat",
"species_evolutions.dat",
"species_metrics.dat",
"species_movesets.dat",
"tm.dat",
"town_map.dat", "town_map.dat",
"trainer_lists.dat", "trainer_lists.dat",
"trainer_types.dat", "trainer_types.dat",

View File

@@ -142,10 +142,12 @@ module Compiler
# contents is a hash containing all the XXX=YYY lines in that section, where # contents is a hash containing all the XXX=YYY lines in that section, where
# the keys are the XXX and the values are the YYY (as unprocessed strings). # the keys are the XXX and the values are the YYY (as unprocessed strings).
schema = GameData::Type::SCHEMA schema = GameData::Type::SCHEMA
pbEachFileSection(f) { |contents, type_number| pbEachFileSection3(f) { |contents, type_id|
contents["InternalName"] = type_id if !type_id[/^\d+/]
id_number = (type_id[/^\d+/]) ? type_id.to_i : nil
# Go through schema hash of compilable data and compile this section # Go through schema hash of compilable data and compile this section
for key in schema.keys for key in schema.keys
FileLineData.setSection(type_number, key, contents[key]) # For error reporting FileLineData.setSection(type_id, key, contents[key]) # For error reporting
# Skip empty properties, or raise an error if a required property is # Skip empty properties, or raise an error if a required property is
# empty # empty
if contents[key].nil? if contents[key].nil?
@@ -166,20 +168,19 @@ module Compiler
end end
end end
# Construct type hash # Construct type hash
type_symbol = contents["InternalName"].to_sym
type_hash = { type_hash = {
:id => type_symbol, :id => contents["InternalName"].to_sym,
:id_number => type_number, :name => contents["Name"],
:name => contents["Name"], :pseudo_type => contents["IsPseudoType"],
:pseudo_type => contents["IsPseudoType"], :special_type => contents["IsSpecialType"],
:special_type => contents["IsSpecialType"], :weaknesses => contents["Weaknesses"],
:weaknesses => contents["Weaknesses"], :resistances => contents["Resistances"],
:resistances => contents["Resistances"], :immunities => contents["Immunities"],
:immunities => contents["Immunities"] :icon_position => contents["IconPosition"] || id_number
} }
# Add type's data to records # Add type's data to records
GameData::Type.register(type_hash) GameData::Type.register(type_hash)
type_names[type_number] = type_hash[:name] type_names.push(type_hash[:name])
} }
} }
# Ensure all weaknesses/resistances/immunities are valid types # Ensure all weaknesses/resistances/immunities are valid types
@@ -199,7 +200,7 @@ module Compiler
end end
# Save all data # Save all data
GameData::Type.save GameData::Type.save
MessageTypes.setMessages(MessageTypes::Types, type_names) MessageTypes.setMessagesAsHash(MessageTypes::Types, type_names)
Graphics.update Graphics.update
end end
@@ -481,7 +482,7 @@ module Compiler
:height => contents["Height"], :height => contents["Height"],
:weight => contents["Weight"], :weight => contents["Weight"],
:color => contents["Color"], :color => contents["Color"],
:shape => GameData::BodyShape.get(contents["Shape"]).id, :shape => contents["Shape"],
:habitat => contents["Habitat"], :habitat => contents["Habitat"],
:generation => contents["Generation"], :generation => contents["Generation"],
:back_sprite_x => contents["BattlerPlayerX"], :back_sprite_x => contents["BattlerPlayerX"],

View File

@@ -138,9 +138,9 @@ module Compiler
# Write each type in turn # Write each type in turn
GameData::Type.each do |type| GameData::Type.each do |type|
f.write("\#-------------------------------\r\n") f.write("\#-------------------------------\r\n")
f.write("[#{type.id_number}]\r\n") f.write("[#{type.id}]\r\n")
f.write("Name = #{type.real_name}\r\n") f.write("Name = #{type.real_name}\r\n")
f.write("InternalName = #{type.id}\r\n") f.write("IconPosition = #{type.icon_position}\r\n")
f.write("IsPseudoType = true\r\n") if type.pseudo_type f.write("IsPseudoType = true\r\n") if type.pseudo_type
f.write("IsSpecialType = true\r\n") if type.special? f.write("IsSpecialType = true\r\n") if type.special?
f.write("Weaknesses = #{type.weaknesses.join(",")}\r\n") if type.weaknesses.length > 0 f.write("Weaknesses = #{type.weaknesses.join(",")}\r\n") if type.weaknesses.length > 0

View File

@@ -1,128 +1,128 @@
# See the documentation on the wiki to learn how to edit this file. # See the documentation on the wiki to learn how to edit this file.
#------------------------------- #-------------------------------
[0] [NORMAL]
Name = Normal Name = Normal
InternalName = NORMAL IconPosition = 0
Weaknesses = FIGHTING Weaknesses = FIGHTING
Immunities = GHOST Immunities = GHOST
#------------------------------- #-------------------------------
[1] [FIGHTING]
Name = Fighting Name = Fighting
InternalName = FIGHTING IconPosition = 1
Weaknesses = FLYING,PSYCHIC,FAIRY Weaknesses = FLYING,PSYCHIC,FAIRY
Resistances = ROCK,BUG,DARK Resistances = ROCK,BUG,DARK
#------------------------------- #-------------------------------
[2] [FLYING]
Name = Flying Name = Flying
InternalName = FLYING IconPosition = 2
Weaknesses = ROCK,ELECTRIC,ICE Weaknesses = ROCK,ELECTRIC,ICE
Resistances = FIGHTING,BUG,GRASS Resistances = FIGHTING,BUG,GRASS
Immunities = GROUND Immunities = GROUND
#------------------------------- #-------------------------------
[3] [POISON]
Name = Poison Name = Poison
InternalName = POISON IconPosition = 3
Weaknesses = GROUND,PSYCHIC Weaknesses = GROUND,PSYCHIC
Resistances = FIGHTING,POISON,BUG,GRASS,FAIRY Resistances = FIGHTING,POISON,BUG,GRASS,FAIRY
#------------------------------- #-------------------------------
[4] [GROUND]
Name = Ground Name = Ground
InternalName = GROUND IconPosition = 4
Weaknesses = WATER,GRASS,ICE Weaknesses = WATER,GRASS,ICE
Resistances = POISON,ROCK Resistances = POISON,ROCK
Immunities = ELECTRIC Immunities = ELECTRIC
#------------------------------- #-------------------------------
[5] [ROCK]
Name = Rock Name = Rock
InternalName = ROCK IconPosition = 5
Weaknesses = FIGHTING,GROUND,STEEL,WATER,GRASS Weaknesses = FIGHTING,GROUND,STEEL,WATER,GRASS
Resistances = NORMAL,FLYING,POISON,FIRE Resistances = NORMAL,FLYING,POISON,FIRE
#------------------------------- #-------------------------------
[6] [BUG]
Name = Bug Name = Bug
InternalName = BUG IconPosition = 6
Weaknesses = FLYING,ROCK,FIRE Weaknesses = FLYING,ROCK,FIRE
Resistances = FIGHTING,GROUND,GRASS Resistances = FIGHTING,GROUND,GRASS
#------------------------------- #-------------------------------
[7] [GHOST]
Name = Ghost Name = Ghost
InternalName = GHOST IconPosition = 7
Weaknesses = GHOST,DARK Weaknesses = GHOST,DARK
Resistances = POISON,BUG Resistances = POISON,BUG
Immunities = NORMAL,FIGHTING Immunities = NORMAL,FIGHTING
#------------------------------- #-------------------------------
[8] [STEEL]
Name = Steel Name = Steel
InternalName = STEEL IconPosition = 8
Weaknesses = FIGHTING,GROUND,FIRE Weaknesses = FIGHTING,GROUND,FIRE
Resistances = NORMAL,FLYING,ROCK,BUG,STEEL,GRASS,PSYCHIC,ICE,DRAGON,FAIRY Resistances = NORMAL,FLYING,ROCK,BUG,STEEL,GRASS,PSYCHIC,ICE,DRAGON,FAIRY
Immunities = POISON Immunities = POISON
#------------------------------- #-------------------------------
[9] [QMARKS]
Name = ??? Name = ???
InternalName = QMARKS IconPosition = 9
IsPseudoType = true IsPseudoType = true
#------------------------------- #-------------------------------
[10] [FIRE]
Name = Fire Name = Fire
InternalName = FIRE IconPosition = 10
IsSpecialType = true IsSpecialType = true
Weaknesses = GROUND,ROCK,WATER Weaknesses = GROUND,ROCK,WATER
Resistances = BUG,STEEL,FIRE,GRASS,ICE,FAIRY Resistances = BUG,STEEL,FIRE,GRASS,ICE,FAIRY
#------------------------------- #-------------------------------
[11] [WATER]
Name = Water Name = Water
InternalName = WATER IconPosition = 11
IsSpecialType = true IsSpecialType = true
Weaknesses = GRASS,ELECTRIC Weaknesses = GRASS,ELECTRIC
Resistances = STEEL,FIRE,WATER,ICE Resistances = STEEL,FIRE,WATER,ICE
#------------------------------- #-------------------------------
[12] [GRASS]
Name = Grass Name = Grass
InternalName = GRASS IconPosition = 12
IsSpecialType = true IsSpecialType = true
Weaknesses = FLYING,POISON,BUG,FIRE,ICE Weaknesses = FLYING,POISON,BUG,FIRE,ICE
Resistances = GROUND,WATER,GRASS,ELECTRIC Resistances = GROUND,WATER,GRASS,ELECTRIC
#------------------------------- #-------------------------------
[13] [ELECTRIC]
Name = Electric Name = Electric
InternalName = ELECTRIC IconPosition = 13
IsSpecialType = true IsSpecialType = true
Weaknesses = GROUND Weaknesses = GROUND
Resistances = FLYING,STEEL,ELECTRIC Resistances = FLYING,STEEL,ELECTRIC
#------------------------------- #-------------------------------
[14] [PSYCHIC]
Name = Psychic Name = Psychic
InternalName = PSYCHIC IconPosition = 14
IsSpecialType = true IsSpecialType = true
Weaknesses = BUG,GHOST,DARK Weaknesses = BUG,GHOST,DARK
Resistances = FIGHTING,PSYCHIC Resistances = FIGHTING,PSYCHIC
#------------------------------- #-------------------------------
[15] [ICE]
Name = Ice Name = Ice
InternalName = ICE IconPosition = 15
IsSpecialType = true IsSpecialType = true
Weaknesses = FIGHTING,ROCK,STEEL,FIRE Weaknesses = FIGHTING,ROCK,STEEL,FIRE
Resistances = ICE Resistances = ICE
#------------------------------- #-------------------------------
[16] [DRAGON]
Name = Dragon Name = Dragon
InternalName = DRAGON IconPosition = 16
IsSpecialType = true IsSpecialType = true
Weaknesses = ICE,DRAGON,FAIRY Weaknesses = ICE,DRAGON,FAIRY
Resistances = FIRE,WATER,GRASS,ELECTRIC Resistances = FIRE,WATER,GRASS,ELECTRIC
#------------------------------- #-------------------------------
[17] [DARK]
Name = Dark Name = Dark
InternalName = DARK IconPosition = 17
IsSpecialType = true IsSpecialType = true
Weaknesses = FIGHTING,BUG,FAIRY Weaknesses = FIGHTING,BUG,FAIRY
Resistances = GHOST,DARK Resistances = GHOST,DARK
Immunities = PSYCHIC Immunities = PSYCHIC
#------------------------------- #-------------------------------
[18] [FAIRY]
Name = Fairy Name = Fairy
InternalName = FAIRY IconPosition = 18
IsSpecialType = true IsSpecialType = true
Weaknesses = POISON,STEEL Weaknesses = POISON,STEEL
Resistances = FIGHTING,BUG,DARK Resistances = FIGHTING,BUG,DARK