diff options
Diffstat (limited to '')
-rw-r--r-- | worldmap_gen.rb | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/worldmap_gen.rb b/worldmap_gen.rb index e52eefc..6169acf 100644 --- a/worldmap_gen.rb +++ b/worldmap_gen.rb @@ -5,6 +5,75 @@ File::open("#{ARGV[0]}.xml") do |f| doc = REXML::Document.new(f.read) end + +# this code is a mess + + +$events = {} +$current_event_id = 0 + +def make_event_number(name) + return $events[name] if $events.key?(name) + + puts "making event for #{name}" + + $events[name] = $current_event_id + $current_event_id += 1 + + if /(?<level_name>.+)_(?<type>normal|special)/ =~ name + raise "level #{level_name} not known" unless $points.key?(level_name) + + point = $points[level_name] + point.params[2] = $events[name] if type == 'normal' + point.params[3] = $events[name] if type == 'special' + end + + $events[name] +end + + + +class StringTable + attr_reader :size + attr_accessor :start_offset + + def initialize + @strings = [] + @offset_hash = {} + @size = 0 + @start_offset = 0 + end + + def include?(str) + @offset_hash.key? str + end + + def push(str) + return if include? str + + str = str.dup + @strings << str + @offset_hash[str] = @size + @size += str.length + 1 + end + + def offset(str) + @start_offset + @offset_hash[str] + end + + def to_a + @strings.dup + end + + def to_s + out = [] + @strings.each {|str| out << str; out << "\0" } + out.join '' + end + + alias :<< :push +end + class Exit attr_accessor :path attr_accessor :reverse @@ -41,6 +110,20 @@ class Point @type = type.value unless type.nil? @params = params.value.split(',').collect { |v| v.to_i } unless params.nil? + if @type == 'level' + level = element.attribute('level').value.split('-').map(&:to_i) + #normal_event = element.attribute('event') + #special_event = element.attribute('special_event') + + #normal_event = normal_event.nil? ? 0xFFFF : normal_event.value.to_i + #special_event = special_event.nil? ? 0xFFFF : special_event.value.to_i + + # phased those out for now + normal_event, special_event = 0xFFFF, 0xFFFF + + @params = level + [normal_event, special_event] + end + element.each_element 'exit' do |e| @exits[e.attribute('direction').value] = Exit.new(e) end @@ -143,6 +226,8 @@ class Path attr_accessor :start_point attr_accessor :end_point attr_reader :id + attr_accessor :materials + attr_accessor :event def initialize(element) @start_point = element.attribute('start').value @@ -156,6 +241,17 @@ class Path @segment_ids << @segments.last.id end + @materials = [] + element.each_element 'material' do |m| + @materials << m.get_text.value.strip + end + + event_attrib = element.attribute('required') + @event = 0xFFFFFFFF + unless event_attrib.nil? + @event = make_event_number(event_attrib.value) + end + @id = $path_id $path_id += 1 end @@ -182,6 +278,8 @@ end directions = {'left' => 0, 'right' => 1, 'up' => 2, 'down' => 3} +$string_table = StringTable.new + # first, collect every point $points = {} $point_id = 0 @@ -236,7 +334,7 @@ File::open("#{ARGV[0]}.wm", "w") do |f| current_offset = data_offset $paths.each_value do |p| f << [current_offset].pack('N') - current_offset += 0xC + (p.segments.count * 4) + current_offset += 0xC + (p.segments.count * 4) + (p.materials.count * 4) end $points.each_value do |p| @@ -250,12 +348,20 @@ File::open("#{ARGV[0]}.wm", "w") do |f| end # nothing for actions yet! + + # write the string table + $string_table.start_offset = current_offset # now write the data $paths.each_value do |p| f << [$points[p.start_point].id, $points[p.end_point].id].pack('NN') - f << [p.segments.count].pack('N') + f << [p.event, p.segments.count, p.materials.count].pack('ncc') f << p.segment_ids.pack('N*') + + p.materials.each do |mat| + $string_table << mat + f << [$string_table.offset(mat)].pack('N') + end end $points.each_value do |p| @@ -287,5 +393,7 @@ File::open("#{ARGV[0]}.wm", "w") do |f| end f << [0].pack('N') end + + f << $string_table.to_s end |