module Core::Parse::TMX

Public Class Methods

parse(file) click to toggle source
# File lib/parse_tmx.rb, line 17
def self.parse(file)
  f = File.open("#{Core::LIBRARY_PATH}/maps/#{file}.tmx", "r")
  doc = Document.new(f)
  f.close
  root = doc.root
  properties = {}
  tilesets = []
  layers = []
  objects = []
  mod = nil
  
  props = root.get_elements("properties")
  props.each { |prop|
    prop.each_element { |el|
      properties.store(el.attribute("name").to_s.to_sym, el.attribute("value").to_s)
    }
  }
  properties.store(:width, root.attribute("width").to_s.to_i)
  properties.store(:height, root.attribute("height").to_s.to_i)
  properties.store(:file, file)
  
  ts = root.get_elements("tileset")
  ts.each { |set|
    img = set.get_elements("image").first
    tile_props = {}
    set.get_elements("tile").each { |tile|
      hash = {}
      tile.get_elements("properties/property").each { |p|
        hash.store(p.attribute("name").to_s.to_sym, p.attribute("value").to_s)
      }
      tile_props.store(tile.attribute("id").to_s.to_i, hash)
    }
    tilesets.push(
      Core::Tileset.new(
        set.attribute("firstgid"),
        set.attribute("name"),
        "graphics/tiles/#{File.basename(img.attribute("source").to_s)}",
        tile_props)
    )
  }
  
  layer_elements = root.get_elements("layer")
  layer_elements.each { |layer|
    w = layer.attribute("width").to_s.to_i
    h = layer.attribute("height").to_s.to_i
    props = {:name => layer.attribute("name").to_s}
    layer.get_elements("properties/property").each { |el|
      props.store(el.attribute("name").to_s.to_sym, el.attribute("value").to_s)
    }
    data = layer.get_elements("data").first
    tiles = []
    line = data.text.gsub("\n", "")
    line.each_line(",") { |val|
      tiles.push(val.gsub(",", "").to_i)
    }
    layers.push(Core::Layer.new(w, h, props, tiles))
    layers.last.fill_tilemap(tilesets.last)
  }

  # retrieves the module from the corresponding file, if it exists
  mod = Maps
  if File.exist?("maps/def/#{file}.rb")
    Kernel.load("maps/def/#{file}.rb")
    names = file.split("/")
    names.each do |name|
      mod = mod.const_get(name.capitalize)
    end
    mod.pre_spawn
  end
  
  objectgrous = root.get_elements("objectgroup")
  objectgrous.each { |objectgroup|
    objectgroup.each_element { |el|
      x = el.attribute("x").to_s.to_i
      y = el.attribute("y").to_s.to_i
      props = {}
      el.get_elements("properties/property").each { |p|
        props.store(p.attribute("name").to_s.to_sym, p.attribute("value").to_s)
      }
      props.store(:layer, objectgroup.attributes["name"])
      props.store(:id, el.attribute("name").to_s.gsub("-", "_"))
      case el.attribute("type").to_s.to_sym
      when :npc
        obj = Core::Game::MapNPC.new(x, y, props)
        obj.behaviour = Core::Parse.behaviour(file, obj)
      else
        obj = Core::Game::MapObject(x, y, props)
      end
      objects.push(obj)
    }
  }
  
  return Core::Game::Map.new(properties, layers, objects, mod)
end