/* * Parsers.cpp * * Created on: Dec 2, 2016 * Author: tibi */ #include #include using namespace farmlands::resources; namespace farmlands { namespace storage { /****** Components ******/ void parseBackgroundCells(resources::ResourceId cellsResource, components::Background* back, size_t layer) { Assert(RInfo[cellsResource].type == ResourceType::BackgroundLayer, "Resource must be a level layer."); char buffer[1024 * 10]; // Open file std::string pathIn = ResourceManager::instance().getPath(cellsResource); std::ifstream in(pathIn); if (!in) THROW(utils::ResourceLoadException, "Could not load level layer " + pathIn); // Read CSV file line by line for (size_t row = 0; row < back->rowCount(); row++) { in.getline(buffer, sizeof(buffer)); if (in.eof()) THROW(utils::ResourceLoadException, "Unexpected end of file " + pathIn); // Separated by comma (or maybe semicolon) char* nextNum = strtok(buffer, ",;"); for (size_t col = 0; col < back->columnCount() && nextNum != NULL; col++) { components::Cell cell = (components::Cell) strtol(nextNum, NULL, 10); back->setCell(layer, row, col, cell); nextNum = strtok(NULL, ",;"); } } in.close(); } template <> components::Background* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Background") root = root.front().second; // This object can be declared in another file std::string src = root.get(".src", ""); if (!src.empty()) { ResourceId id = ResourceManager::instance().getId(src); return parse(id); } // Read sizes uint32_t layers = root.count("Layer"); uint32_t rows = root.get(".rows"); uint32_t cols = root.get(".columns"); // Create components::Background object components::Background* back = new components::Background(layers, rows, cols); // Read layers size_t layerNum = 0; for (auto layer : root) { if (layer.first == "Layer") { // Read cells std::string cellsPath = layer.second.get(".cells"); resources::ResourceId cellsId = resources::ResourceManager::instance().getId(cellsPath); parseBackgroundCells(cellsId, back, layerNum); // Read texture name std::string texPath = layer.second.get(".texture"); resources::ResourceId tex = resources::ResourceManager::instance().getId(texPath); back->setTexture(layerNum, tex); ++layerNum; } } return back; } template <> components::basic::Camera* parse (boost::property_tree::ptree& root) { if (root.front().first == "Camera") root = root.front().second; components::basic::Camera* camera = new components::basic::Camera(); camera->scale = root.get(".scale", 1.0f); camera->mainCamera = root.get(".mainCamera", false); return camera; } template <> components::basic::Frame* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Frame") root = root.front().second; components::basic::Frame* frame = new components::basic::Frame(); // Obtine tile set id std::string tileSetPath = root.get(".tileSet"); frame->tileSetId = resources::ResourceManager::instance().getId(tileSetPath); // Set properties frame->tileSetCell = root.get(".cell"); frame->width = root.get(".w", 1u); frame->height = root.get(".h", 1u); frame->duration = root.get(".duration"); return frame; } template <> components::basic::Sprite* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Sprite") root = root.front().second; // This object can be declared in another file std::string src = root.get(".src", ""); if (!src.empty()) { ResourceId id = ResourceManager::instance().getId(src); return parse(id); } // Parse components::basic::Sprite components::basic::Sprite* sprite = new components::basic::Sprite(); sprite->anchorX = root.get(".anchorX"); sprite->anchorY = root.get(".anchorY"); sprite->animationVelocity = root.get(".animationVelocity", 1.0f); for (auto child : root) { if (child.first == "State") { components::basic::SpriteState* state = parse(child.second); sprite->addState(*state); delete state; } } return sprite; } template <> components::basic::SpriteState* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "SpriteState") root = root.front().second; components::basic::SpriteState* spriteState = new components::basic::SpriteState(); spriteState->name = root.get(".name"); for (auto child : root) { if (child.first == "Frame") { components::basic::Frame* frame = parse(child.second); spriteState->frames.push_back(*frame); delete frame; } } return spriteState; } template <> components::basic::Transform* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Transform") root = root.front().second; components::basic::Transform* transform = new components::basic::Transform(); transform->x = root.get(".x", 0.0f); transform->y = root.get(".y", 0.0f); transform->w = root.get(".w", 0.0f); transform->h = root.get(".h", 0.0f); return transform; } template <> components::DebugController* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "DebugController") root = root.front().second; components::DebugController* controller = new components::DebugController(); return controller; } template <> components::items::Axe* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Axe") root = root.front().second; // Parse return new components::items::Axe(); } template <> components::items::Giftable* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Giftable") root = root.front().second; // Parse return new components::items::Giftable(); } template <> components::items::Hoe* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Hoe") root = root.front().second; // Parse return new components::items::Hoe(); } template <> components::items::Item* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Item") root = root.front().second; // Parse components::items::Item* item = new components::items::Item(); item->name = root.get(".name"); item->description = root.get(".description"); item->level = root.get(".level"); return item; } template <> components::items::Pickaxe* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Pickaxe") root = root.front().second; // Parse return new components::items::Pickaxe(); } template <> components::items::Scythe* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Pickaxe") root = root.front().second; // Parse return new components::items::Scythe(); } template <> components::items::WateringCan* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "WateringCan") root = root.front().second; // Parse components::items::WateringCan* can = new components::items::WateringCan(); can->capacity = root.get(".capacity"); can->amountLeft = root.get(".amountLeft"); return can; } template <> components::items::Weapon* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Weapon") root = root.front().second; // Parse components::items::Weapon* weapon = new components::items::Weapon(); weapon->damage = root.get(".damage"); weapon->critProbability = root.get(".critProbability"); weapon->critDamage = root.get(".critDamage"); weapon->attackDuration = root.get(".attackDuration"); return weapon; } template <> components::player::PlayerInventory* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "PlayerInventory") root = root.front().second; components::player::PlayerInventory* controller = new components::player::PlayerInventory(); controller->capacity = root.get(".capacity"); controller->currentItemIndex = root.get(".currentItemIndex", -1); return controller; } template <> components::player::PlayerMovement* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "PlayerMovement") root = root.front().second; components::player::PlayerMovement* controller = new components::player::PlayerMovement(); controller->facingDirection = (model::Direction)root.get(".facingDirection", model::Direction::South); return controller; } /****** Graphics ******/ template <> graphics::BackgroundRenderer* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "BackgroundRenderer") root = root.front().second; graphics::BackgroundRenderer* renderer = new graphics::BackgroundRenderer(); return renderer; } template <> graphics::SpriteRenderer* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "SpriteRenderer") root = root.front().second; graphics::SpriteRenderer* renderer = new graphics::SpriteRenderer(); return renderer; } /****** Model ******/ template <> model::GameObject* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "GameObject") root = root.front().second; model::GameObject* gameObj = new model::GameObject(); gameObj->name = root.get(".name"); gameObj->visible = root.get(".visible", true); gameObj->setEnabled(root.get(".enabled", true)); for (auto child : root) { // Game object if (child.first == "GameObject") gameObj->addChild(parse(child.second)); // Components::basic else if (child.first == "Camera") gameObj->addComponent(parse(child.second)); else if (child.first == "Sprite") gameObj->addComponent(parse(child.second)); else if (child.first == "Transform") gameObj->addComponent(parse(child.second)); // Components::items else if (child.first == "Axe") gameObj->addComponent(parse(child.second)); else if (child.first == "Giftable") gameObj->addComponent(parse(child.second)); else if (child.first == "Hoe") gameObj->addComponent(parse(child.second)); else if (child.first == "Item") gameObj->addComponent(parse(child.second)); else if (child.first == "Pickaxe") gameObj->addComponent(parse(child.second)); else if (child.first == "Scythe") gameObj->addComponent(parse(child.second)); else if (child.first == "WateringCan") gameObj->addComponent(parse(child.second)); else if (child.first == "Weapon") gameObj->addComponent(parse(child.second)); // Components::player else if (child.first == "PlayerInventory") gameObj->addComponent(parse(child.second)); else if (child.first == "PlayerMovement") gameObj->addComponent(parse(child.second)); // Components else if (child.first == "Background") gameObj->addComponent(parse(child.second)); else if (child.first == "DebugController") gameObj->addComponent(parse(child.second)); // Graphics else if (child.first == "BackgroundRenderer") gameObj->addComponent(parse(child.second)); else if (child.first == "SpriteRenderer") gameObj->addComponent(parse(child.second)); // !!! Add additional types here !!! } return gameObj; } template <> model::Configuration* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Configuration") root = root.front().second; model::Configuration* config = new model::Configuration(); config->animationFps = root.get("animationFps"); return config; } template <> model::Scene* parse (boost::property_tree::ptree& root) { // Ensure we are on the model::Scene node (property tree seems to add root of its own) if (root.front().first == "Scene") root = root.front().second; model::Scene* scene = new model::Scene(); scene->cellWidth = root.get(".cellWidth"); scene->cellHeight = root.get(".cellHeight"); for (auto child : root) { if (child.first == "GameObject") { model::GameObject* obj = parse(child.second); scene->root.addChild(obj); } } return scene; } } }