Пример #1
0
ControllerPtr
Manager::create_controller(const Pathname& filename)
{
  ControllerPtr controller(new Controller(desc));

  ReaderObject reader_object = Reader::parse(filename);

  if (reader_object.get_name() != "pingus-controller")
  {
    raise_exception(std::runtime_error,
                    "Controller: invalid config file '" << filename.str() << "'");
  }
  else
  {
    ReaderMapping reader = reader_object.get_mapping();

    ReaderMapping controls_mapping;
    if (!reader.read_mapping("controls", controls_mapping))
    {
      log_warn("%1%: 'controls' section missing", filename);
    }
    else
    {
      for (const auto& key : controls_mapping.get_keys())
      {
        ReaderCollection collection;
        if (!controls_mapping.read_collection(key.c_str(), collection))
        {
          log_error("%1%: mapping must contain object at %2%", filename, key);
        }
        else
        {
          if (StringUtil::has_suffix(key, "pointer"))
          {
            int id = desc.get_definition(key).id;
            ControllerPointer* ctrl_pointer = controller->get_pointer(id);
            for(const auto& object : collection.get_objects())
            {
              auto pointer = create_pointer(object, ctrl_pointer);
              if (pointer)
              {
                ctrl_pointer->add_pointer(std::move(pointer));
              }
              else
              {
                log_error("Manager: pointer: Couldn't create pointer %1%", object.get_name());
              }
            }
          }
          else if (StringUtil::has_suffix(key, "scroller"))
          {
            int id = desc.get_definition(key).id;
            ControllerScroller* ctrl_scroller = controller->get_scroller(id);
            for(const auto& object : collection.get_objects())
            {
              auto scroller = create_scroller(object, ctrl_scroller);
              if (scroller)
              {
                ctrl_scroller->add_scroller(std::move(scroller));
              }
              else
              {
                log_error("Manager: scroller: Couldn't create scroller %1%", object.get_name());
              }
            }
          }
          else if (StringUtil::has_suffix(key, "button"))
          {
            int id = desc.get_definition(key).id;
            ControllerButton* ctrl_button = controller->get_button(id);
            for(const auto& object : collection.get_objects())
            {
              auto button = create_button(object, ctrl_button);
              if (button)
              {
                ctrl_button->add_button(std::move(button));
              }
              else
              {
                log_error("Manager: button: Couldn't create button %1%", object.get_name());
              }
            }
          }
          else if (StringUtil::has_suffix(key, "axis"))
          {
            int id = desc.get_definition(key).id;
            ControllerAxis* ctrl_axis = controller->get_axis(id);
            for(const auto& object : collection.get_objects())
            {
              auto axis = create_axis(object, ctrl_axis);
              if (axis)
              {
                ctrl_axis->add_axis(std::move(axis));
              }
              else
              {
                log_error("Manager: axis: Couldn't create axis %1%", object.get_name());
              }
            }
          }
          else if (StringUtil::has_suffix(key, "keyboard"))
          {
            int id = desc.get_definition(key).id;
            ControllerKeyboard* ctrl_keyboard = controller->get_keyboard(id);
            for(const auto& object : collection.get_objects())
            {
              std::unique_ptr<Keyboard> keyboard = create_keyboard(object, ctrl_keyboard);
              if (keyboard)
              {
                ctrl_keyboard->add_keyboard(std::move(keyboard));
              }
              else
              {
                log_error("Manager: keyboard: Couldn't create keyboard %1%", object.get_name());
              }
            }
          }
          else
          {
            raise_exception(std::runtime_error, "Manager: Unkown Element in Controller Config: "
                            << key);
          }
        }
      }
    }
  }

  controllers.push_back(controller);
  return controller;
}
Пример #2
0
void
SectorParser::parse_old_format(const ReaderMapping& reader)
{
  m_sector.name = "main";
  reader.get("gravity", m_sector.gravity);

  std::string backgroundimage;
  if (reader.get("background", backgroundimage) && (backgroundimage != "")) {
    if (backgroundimage == "arctis.png") backgroundimage = "arctis.jpg";
    if (backgroundimage == "arctis2.jpg") backgroundimage = "arctis.jpg";
    if (backgroundimage == "ocean.png") backgroundimage = "ocean.jpg";
    backgroundimage = "images/background/" + backgroundimage;
    if (!PHYSFS_exists(backgroundimage.c_str())) {
      log_warning << "Background image \"" << backgroundimage << "\" not found. Ignoring." << std::endl;
      backgroundimage = "";
    }
  }

  float bgspeed = .5;
  reader.get("bkgd_speed", bgspeed);
  bgspeed /= 100;

  Color bkgd_top, bkgd_bottom;
  int r = 0, g = 0, b = 128;
  reader.get("bkgd_red_top", r);
  reader.get("bkgd_green_top",  g);
  reader.get("bkgd_blue_top",  b);
  bkgd_top.red = static_cast<float> (r) / 255.0f;
  bkgd_top.green = static_cast<float> (g) / 255.0f;
  bkgd_top.blue = static_cast<float> (b) / 255.0f;

  reader.get("bkgd_red_bottom",  r);
  reader.get("bkgd_green_bottom", g);
  reader.get("bkgd_blue_bottom", b);
  bkgd_bottom.red = static_cast<float> (r) / 255.0f;
  bkgd_bottom.green = static_cast<float> (g) / 255.0f;
  bkgd_bottom.blue = static_cast<float> (b) / 255.0f;

  if(backgroundimage != "") {
    auto background = std::make_shared<Background>();
    background->set_image(backgroundimage, bgspeed);
    m_sector.add_object(background);
  } else {
    auto gradient = std::make_shared<Gradient>();
    gradient->set_gradient(bkgd_top, bkgd_bottom);
    m_sector.add_object(gradient);
  }

  std::string particlesystem;
  reader.get("particle_system", particlesystem);
  if(particlesystem == "clouds")
    m_sector.add_object(std::make_shared<CloudParticleSystem>());
  else if(particlesystem == "snow")
    m_sector.add_object(std::make_shared<SnowParticleSystem>());
  else if(particlesystem == "rain")
    m_sector.add_object(std::make_shared<RainParticleSystem>());

  Vector startpos(100, 170);
  reader.get("start_pos_x", startpos.x);
  reader.get("start_pos_y", startpos.y);

  auto spawn = std::make_shared<SpawnPoint>();
  spawn->pos = startpos;
  spawn->name = "main";
  m_sector.spawnpoints.push_back(spawn);

  m_sector.music = "chipdisko.ogg";
  // skip reading music filename. It's all .ogg now, anyway
  /*
    reader.get("music", music);
  */
  m_sector.music = "music/" + m_sector.music;

  int width = 30, height = 15;
  reader.get("width", width);
  reader.get("height", height);

  std::vector<unsigned int> tiles;
  if(reader.get("interactive-tm", tiles)
     || reader.get("tilemap", tiles)) {
    auto tileset = TileManager::current()->get_tileset(m_sector.level->get_tileset());
    auto tilemap = std::make_shared<TileMap>(tileset);
    tilemap->set(width, height, tiles, LAYER_TILES, true);

    // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
    for(size_t x=0; x < tilemap->get_width(); ++x) {
      for(size_t y=0; y < tilemap->get_height(); ++y) {
        uint32_t id = tilemap->get_tile_id(x, y);
        if(id == 112)
          tilemap->change(x, y, 1311);
      }
    }

    if (height < 19) tilemap->resize(width, 19);
    m_sector.add_object(tilemap);
  }

  if(reader.get("background-tm", tiles)) {
    auto tileset = TileManager::current()->get_tileset(m_sector.level->get_tileset());
    auto tilemap = std::make_shared<TileMap>(tileset);
    tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
    if (height < 19) tilemap->resize(width, 19);
    m_sector.add_object(tilemap);
  }

  if(reader.get("foreground-tm", tiles)) {
    auto tileset = TileManager::current()->get_tileset(m_sector.level->get_tileset());
    auto tilemap = std::make_shared<TileMap>(tileset);
    tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);

    // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
    if (height < 19) tilemap->resize(width, 19, 2035);

    m_sector.add_object(tilemap);
  }

  // read reset-points (now spawn-points)
  ReaderMapping resetpoints;
  if(reader.get("reset-points", resetpoints)) {
    auto iter = resetpoints.get_iter();
    while(iter.next()) {
      if(iter.get_key() == "point") {
        Vector sp_pos;
        if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
        {
          auto sp = std::make_shared<SpawnPoint>();
          sp->name = "main";
          sp->pos = sp_pos;
          m_sector.spawnpoints.push_back(sp);
        }
      } else {
        log_warning << "Unknown token '" << iter.get_key() << "' in reset-points." << std::endl;
      }
    }
  }

  // read objects
  ReaderCollection objects;
  if(reader.get("objects", objects)) {
    for(auto const& obj : objects.get_objects())
    {
      auto object = parse_object(obj.get_name(), obj.get_mapping());
      if(object) {
        m_sector.add_object(object);
      } else {
        log_warning << "Unknown object '" << obj.get_name() << "' in level." << std::endl;
      }
    }
  }

  // add a camera
  auto camera_ = std::make_shared<Camera>(&m_sector, "Camera");
  m_sector.add_object(camera_);

  m_sector.update_game_objects();

  if (m_sector.solid_tilemaps.empty()) {
    log_warning << "sector '" << m_sector.name << "' does not contain a solid tile layer." << std::endl;
  }

  fix_old_tiles();
  m_sector.update_game_objects();
}
Пример #3
0
void
PingusLevel::load(const std::string& resname,
                  const Pathname& pathname)
{
  impl->checksum = System::checksum(pathname);

  impl->resname = resname;
  ReaderObject reader_object = FileReader::parse(pathname);

  if (reader_object.get_name() != "pingus-level")
  {
    raise_exception(std::runtime_error, "Error: " << pathname.str() << ": not a 'pingus-level' file");
  }
  else
  {
    ReaderMapping reader = reader_object.get_mapping();

    int version;
    if (reader.read_int("version", version))
      log_info("Levelfile Version: %1%", version);
    else
      log_info("Unknown Levelfile Version: %1%", version);

    ReaderMapping head;
    if (!reader.read_mapping("head", head))
    {
      raise_exception(std::runtime_error, "Error: (head) section not found in '" << pathname.str() << "'");
    }
    else
    {
      log_info("Reading head");
      head.read_string("levelname",        impl->levelname);
      head.read_string("description",      impl->description);
      head.read_size  ("levelsize",        impl->size);
      head.read_string("music",            impl->music);
      head.read_int   ("time",             impl->time);
      head.read_int   ("number-of-pingus", impl->number_of_pingus);
      head.read_int   ("number-to-save",   impl->number_to_save);
      head.read_colorf("ambient-light",    impl->ambient_light);
      head.read_string("author",           impl->author);

      log_info("Size: %1%x%2%", impl->size.width, impl->size.height);

      ReaderMapping actions;
      if (head.read_mapping("actions", actions))
      {
        std::vector<std::string> lst = actions.get_keys();
        for(std::vector<std::string>::iterator i = lst.begin(); i != lst.end(); ++i)
        {
          int count = 0;
          log_info("Actions: %1%", i->c_str());
          if (actions.read_int(i->c_str(), count))
            impl->actions[*i] = count;
        }
      }
      else
      {
        raise_exception(std::runtime_error,
                        "Error: (pingus-level head actions) not found in '" << pathname.str() << "'");
      }
    }

    ReaderCollection collection;
    if (reader.read_collection("objects", collection))
    {
      std::vector<ReaderObject> object_lst = collection.get_objects();
      for(auto i = object_lst.begin(); i != object_lst.end(); ++i)
      {
        impl->objects.push_back(*i);
      }
    }
  }
}