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; }
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(); }
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); } } } }