ruby: add decode_mat method for mat_type/mat_index
parent
cb17bde8f4
commit
edf0a9cb3d
@ -0,0 +1,199 @@
|
||||
module DFHack
|
||||
class MaterialInfo
|
||||
attr_accessor :mat_type, :mat_index
|
||||
attr_accessor :mode, :material, :creature, :figure, :plant, :inorganic
|
||||
def initialize(what, idx=nil)
|
||||
case what
|
||||
when Integer
|
||||
@mat_type, @mat_index = what, idx
|
||||
decode_type_index
|
||||
when String
|
||||
decode_string(what)
|
||||
else
|
||||
@mat_type, @mat_index = what.mat_type, what.mat_index
|
||||
decode_type_index
|
||||
end
|
||||
end
|
||||
|
||||
CREATURE_BASE = 19
|
||||
FIGURE_BASE = CREATURE_BASE+200
|
||||
PLANT_BASE = FIGURE_BASE+200
|
||||
END_BASE = PLANT_BASE+200
|
||||
|
||||
# interpret the mat_type and mat_index fields
|
||||
def decode_type_index
|
||||
if @mat_index < 0 or @mat_type >= END_BASE
|
||||
@mode = :Builtin
|
||||
@material = df.world.raws.mat_table.builtin[@mat_type]
|
||||
|
||||
elsif @mat_type >= PLANT_BASE
|
||||
@mode = :Plant
|
||||
@plant = df.world.raws.plants.all[@mat_index]
|
||||
@material = @plant.material[@mat_type-PLANT_BASE] if @plant
|
||||
|
||||
elsif @mat_type >= FIGURE_BASE
|
||||
@mode = :Figure
|
||||
@figure = df.world.history.figures.binsearch(@mat_index)
|
||||
@creature = df.world.raws.creatures.all[@figure.race] if @figure
|
||||
@material = @creature.material[@mat_type-FIGURE_BASE] if @creature
|
||||
|
||||
elsif @mat_type >= CREATURE_BASE
|
||||
@mode = :Creature
|
||||
@creature = df.world.raws.creatures.all[@mat_index]
|
||||
@material = @creature.material[@mat_type-CREATURE_BASE] if @creature
|
||||
|
||||
elsif @mat_type > 0
|
||||
@mode = :Builtin
|
||||
@material = df.world.raws.mat_table.builtin[@mat_type]
|
||||
|
||||
elsif @mat_type == 0
|
||||
@mode = :Inorganic
|
||||
@inorganic = df.world.raws.inorganics[@mat_index]
|
||||
@material = @inorganic.material if @inorganic
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string(str)
|
||||
parts = str.split(':')
|
||||
case parts[0].chomp('_MAT')
|
||||
when 'INORGANIC', 'STONE', 'METAL'
|
||||
decode_string_inorganic(parts)
|
||||
when 'PLANT'
|
||||
decode_string_plant(parts)
|
||||
when 'CREATURE'
|
||||
if parts[3] and parts[3] != 'NONE'
|
||||
decode_string_figure(parts)
|
||||
else
|
||||
decode_string_creature(parts)
|
||||
end
|
||||
when 'INVALID'
|
||||
@mat_type = parts[1].to_i
|
||||
@mat_index = parts[2].to_i
|
||||
else
|
||||
decode_string_builtin(parts)
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string_inorganic(parts)
|
||||
@@inorganics_index ||= (0...df.world.raws.inorganics.length).inject({}) { |h, i| h.update df.world.raws.inorganics[i].id => i }
|
||||
|
||||
@mode = :Inorganic
|
||||
@mat_type = 0
|
||||
|
||||
if parts[1] and parts[1] != 'NONE'
|
||||
@mat_index = @@inorganics_index[parts[1]]
|
||||
raise "invalid inorganic token #{parts.join(':').inspect}" if not @mat_index
|
||||
@inorganic = df.world.raws.inorganics[@mat_index]
|
||||
@material = @inorganic.material
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string_builtin(parts)
|
||||
@@builtins_index ||= (1...df.world.raws.mat_table.builtin.length).inject({}) { |h, i| b = df.world.raws.mat_table.builtin[i] ; b ? h.update(b.id => i) : h }
|
||||
|
||||
@mode = :Builtin
|
||||
@mat_index = -1
|
||||
@mat_type = @@builtins_index[parts[0]]
|
||||
raise "invalid builtin token #{parts.join(':').inspect}" if not @mat_type
|
||||
@material = df.world.raws.mat_table.builtin[@mat_type]
|
||||
|
||||
if parts[0] == 'COAL' and parts[1]
|
||||
@mat_index = ['COKE', 'CHARCOAL'].index(parts[1]) || -1
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string_creature(parts)
|
||||
@@creatures_index ||= (0...df.world.raws.creatures.all.length).inject({}) { |h, i| h.update df.world.raws.creatures.all[i].creature_id => i }
|
||||
|
||||
@mode = :Creature
|
||||
|
||||
if parts[1] and parts[1] != 'NONE'
|
||||
@mat_index = @@creatures_index[parts[1]]
|
||||
raise "invalid creature token #{parts.join(':').inspect}" if not @mat_index
|
||||
@creature = df.world.raws.creatures.all[@mat_index]
|
||||
end
|
||||
|
||||
if @creature and parts[2] and parts[2] != 'NONE'
|
||||
@mat_type = @creature.material.index { |m| m.id == parts[2] }
|
||||
@material = @creature.material[@mat_type]
|
||||
@mat_type += CREATURE_BASE
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string_figure(parts)
|
||||
@mode = :Figure
|
||||
@mat_index = parts[3].to_i
|
||||
@figure = df.world.history.figures.binsearch(@mat_index)
|
||||
raise "invalid creature histfig #{parts.join(':').inspect}" if not @figure
|
||||
|
||||
@creature = df.world.raws.creatures.all[@figure.race]
|
||||
if parts[1] and parts[1] != 'NONE'
|
||||
raise "invalid histfig race #{parts.join(':').inspect}" if @creature.creature_id != parts[1]
|
||||
end
|
||||
|
||||
if @creature and parts[2] and parts[2] != 'NONE'
|
||||
@mat_type = @creature.material.index { |m| m.id == parts[2] }
|
||||
@material = @creature.material[@mat_type]
|
||||
@mat_type += FIGURE_BASE
|
||||
end
|
||||
end
|
||||
|
||||
def decode_string_plant(parts)
|
||||
@@plants_index ||= (0...df.world.raws.plants.all.length).inject({}) { |h, i| h.update df.world.raws.plants.all[i].id => i }
|
||||
|
||||
@mode = :Plant
|
||||
|
||||
if parts[1] and parts[1] != 'NONE'
|
||||
@mat_index = @@plants_index[parts[1]]
|
||||
raise "invalid plant token #{parts.join(':').inspect}" if not @mat_index
|
||||
@plant = df.world.raws.plants.all[@mat_index]
|
||||
end
|
||||
|
||||
if @plant and parts[2] and parts[2] != 'NONE'
|
||||
@mat_type = @plant.material.index { |m| m.id == parts[2] }
|
||||
raise "invalid plant type #{parts.join(':').inspect}" if not @mat_type
|
||||
@material = @plant.material[@mat_type]
|
||||
@mat_type += PLANT_BASE
|
||||
end
|
||||
end
|
||||
|
||||
# delete the caches of raws id => index used in decode_string
|
||||
def self.flush_raws_cache
|
||||
@@inorganics_index = @@plants_index = @@creatures_index = @@builtins_index = nil
|
||||
end
|
||||
|
||||
def token
|
||||
out = []
|
||||
case @mode
|
||||
when :Builtin
|
||||
out << (@material ? @material.id : 'NONE')
|
||||
out << (['COKE', 'CHARCOAL'][@mat_index] || 'NONE') if @material and @material.id == 'COAL' and @mat_index >= 0
|
||||
when :Inorganic
|
||||
out << 'INORGANIC'
|
||||
out << @inorganic.id if @inorganic
|
||||
when :Plant
|
||||
out << 'PLANT_MAT'
|
||||
out << @plant.id if @plant
|
||||
out << @material.id if @plant and @material
|
||||
when :Creature, :Figure
|
||||
out << 'CREATURE_MAT'
|
||||
out << @creature.creature_id if @creature
|
||||
out << @material.id if @creature and @material
|
||||
out << @figure.id.to_s if @creature and @material and @figure
|
||||
else
|
||||
out << 'INVALID'
|
||||
out << @mat_type.to_s
|
||||
out << @mat_index.to_s
|
||||
end
|
||||
out.join(':')
|
||||
end
|
||||
|
||||
def to_s ; token ; end
|
||||
end
|
||||
|
||||
class << self
|
||||
def decode_mat(what, idx=nil)
|
||||
MaterialInfo.new(what, idx)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue