summaryrefslogtreecommitdiff
path: root/worldmap_gen.rb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--worldmap_gen.rb112
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