Implemented many things. Refactored parsers. Added some behaviors and items. Added weapons.
This commit is contained in:
385
src/storage/Parsers.cpp
Normal file
385
src/storage/Parsers.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Parsers.cpp
|
||||
*
|
||||
* Created on: Dec 2, 2016
|
||||
* Author: tibi
|
||||
*/
|
||||
|
||||
#include <storage/Parsers.h>
|
||||
#include <resources/Resources.h>
|
||||
|
||||
using namespace farmlands::resources;
|
||||
|
||||
namespace farmlands {
|
||||
namespace storage {
|
||||
|
||||
/****** Base namespace ******/
|
||||
|
||||
template <>
|
||||
base::Camera* parse<base::Camera> (boost::property_tree::ptree& root)
|
||||
{
|
||||
if (root.front().first == "Camera")
|
||||
root = root.front().second;
|
||||
|
||||
base::Camera* camera = new base::Camera();
|
||||
camera->scale = root.get<float>("<xmlattr>.scale", 1.0f);
|
||||
camera->mainCamera = root.get<bool>("<xmlattr>.mainCamera", false);
|
||||
return camera;
|
||||
}
|
||||
|
||||
template <>
|
||||
base::Frame* parse<base::Frame> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Frame")
|
||||
root = root.front().second;
|
||||
|
||||
base::Frame* frame = new base::Frame();
|
||||
|
||||
// Obtine tile set id
|
||||
std::string tileSetPath = root.get<std::string>("<xmlattr>.tileSet");
|
||||
frame->tileSetId = resources::ResourceManager::instance().getId(tileSetPath);
|
||||
|
||||
// Set properties
|
||||
frame->tileSetCell = root.get<int>("<xmlattr>.cell");
|
||||
frame->width = root.get<uint32_t>("<xmlattr>.w", 1u);
|
||||
frame->height = root.get<uint32_t>("<xmlattr>.h", 1u);
|
||||
frame->duration = root.get<uint32_t>("<xmlattr>.duration");
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
template <>
|
||||
base::GameObject* parse<base::GameObject> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "GameObject")
|
||||
root = root.front().second;
|
||||
|
||||
base::GameObject* gameObj = new base::GameObject();
|
||||
gameObj->name = root.get<std::string>("<xmlattr>.name");
|
||||
|
||||
for (auto child : root)
|
||||
{
|
||||
// Base objects
|
||||
if (child.first == "Transform")
|
||||
gameObj->addComponent(parse<base::Transform>(child.second));
|
||||
|
||||
else if (child.first == "Camera")
|
||||
gameObj->addComponent(parse<base::Camera>(child.second));
|
||||
|
||||
// Model
|
||||
else if (child.first == "Background")
|
||||
{
|
||||
std::string path = child.second.get<std::string>("<xmlattr>.src");
|
||||
resources::ResourceId id = resources::ResourceManager::instance().getId(path);
|
||||
gameObj->addComponent(parse<model::Background>(id));
|
||||
}
|
||||
|
||||
else if (child.first == "Item")
|
||||
gameObj->addComponent(parse<model::Item>(child.second));
|
||||
|
||||
// Graphics
|
||||
else if (child.first == "BackgroundRenderer")
|
||||
gameObj->addComponent(parse<graphics::BackgroundRenderer>(child.second));
|
||||
|
||||
else if (child.first == "SpriteRenderer")
|
||||
gameObj->addComponent(parse<graphics::SpriteRenderer>(child.second));
|
||||
|
||||
// Controllers
|
||||
else if (child.first == "DebugController")
|
||||
gameObj->addComponent(parse<controller::DebugController>(child.second));
|
||||
|
||||
else if (child.first == "Giftable")
|
||||
gameObj->addComponent(parse<controller::items::Giftable>(child.second));
|
||||
|
||||
else if (child.first == "Weapon")
|
||||
gameObj->addComponent(parse<controller::items::Weapon>(child.second));
|
||||
|
||||
else if (child.first == "PlayerController")
|
||||
gameObj->addComponent(parse<controller::player::PlayerController>(child.second));
|
||||
|
||||
// !!! Add additional types here !!!
|
||||
}
|
||||
|
||||
return gameObj;
|
||||
}
|
||||
|
||||
template <>
|
||||
base::Sprite* parse<base::Sprite> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Sprite")
|
||||
root = root.front().second;
|
||||
|
||||
base::Sprite* sprite = new base::Sprite();
|
||||
sprite->anchorX = root.get<float>("<xmlattr>.anchorX");
|
||||
sprite->anchorY = root.get<float>("<xmlattr>.anchorY");
|
||||
|
||||
for (auto child : root)
|
||||
{
|
||||
if (child.first == "State")
|
||||
{
|
||||
base::SpriteState* state = parse<base::SpriteState>(child.second);
|
||||
sprite->addState(*state);
|
||||
delete state;
|
||||
}
|
||||
}
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
template <>
|
||||
base::SpriteState* parse<base::SpriteState> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "SpriteState")
|
||||
root = root.front().second;
|
||||
|
||||
base::SpriteState* spriteState = new base::SpriteState();
|
||||
spriteState->name = root.get<std::string>("<xmlattr>.name");
|
||||
|
||||
for (auto child : root)
|
||||
{
|
||||
if (child.first == "Frame")
|
||||
{
|
||||
base::Frame* frame = parse<base::Frame>(child.second);
|
||||
spriteState->frames.push_back(*frame);
|
||||
delete frame;
|
||||
}
|
||||
}
|
||||
|
||||
return spriteState;
|
||||
}
|
||||
|
||||
template <>
|
||||
base::Transform* parse<base::Transform> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Transform")
|
||||
root = root.front().second;
|
||||
|
||||
base::Transform* transform = new base::Transform();
|
||||
transform->x = root.get<float>("<xmlattr>.x", 0.0f);
|
||||
transform->y = root.get<float>("<xmlattr>.y", 0.0f);
|
||||
transform->w = root.get<float>("<xmlattr>.w", 0.0f);
|
||||
transform->h = root.get<float>("<xmlattr>.h", 0.0f);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
/****** Model namespace ******/
|
||||
|
||||
void parseBackgroundCells(resources::ResourceId cellsResource, model::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++)
|
||||
{
|
||||
model::Cell cell = (model::Cell)strtol(nextNum, NULL, 10);
|
||||
back->setCell(layer, row, col, cell);
|
||||
|
||||
nextNum = strtok(NULL, ",;");
|
||||
}
|
||||
}
|
||||
|
||||
in.close();
|
||||
}
|
||||
|
||||
template <>
|
||||
model::Background* parse<model::Background> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Background")
|
||||
root = root.front().second;
|
||||
|
||||
// Read sizes
|
||||
uint32_t layers = root.count("Layer");
|
||||
uint32_t rows = root.get<uint32_t>("<xmlattr>.rows");
|
||||
uint32_t cols = root.get<uint32_t>("<xmlattr>.columns");
|
||||
|
||||
// Create background object
|
||||
model::Background* back = new model::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<std::string>("<xmlattr>.cells");
|
||||
resources::ResourceId cellsId = resources::ResourceManager::instance().getId(cellsPath);
|
||||
parseBackgroundCells(cellsId, back, layerNum);
|
||||
|
||||
// Read texture name
|
||||
std::string texPath = layer.second.get<std::string>("<xmlattr>.texture");
|
||||
resources::ResourceId tex = resources::ResourceManager::instance().getId(texPath);
|
||||
back->setTexture(layerNum, tex);
|
||||
|
||||
++layerNum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
template <>
|
||||
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the 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<float>("animationFps");
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
template <>
|
||||
model::Item* parse<model::Item> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Item")
|
||||
root = root.front().second;
|
||||
|
||||
// Parse
|
||||
model::Item* item = new model::Item();
|
||||
item->name = root.get<std::string>("<xmlattr>.name");
|
||||
item->description = root.get<std::string>("<xmlattr>.description");
|
||||
item->level = root.get<uint8_t>("<xmlattr>.level");
|
||||
return item;
|
||||
}
|
||||
|
||||
template <>
|
||||
model::Scene* parse<model::Scene> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the 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<uint32_t>("<xmlattr>.cellWidth");
|
||||
scene->cellHeight = root.get<uint32_t>("<xmlattr>.cellHeight");
|
||||
|
||||
for (auto child : root)
|
||||
{
|
||||
if (child.first == "GameObject")
|
||||
{
|
||||
base::GameObject* obj = parse<base::GameObject>(child.second);
|
||||
scene->root.addChild(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
/****** Controller namespace ******/
|
||||
|
||||
template <>
|
||||
controller::DebugController* parse<controller::DebugController> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "DebugController")
|
||||
root = root.front().second;
|
||||
|
||||
controller::DebugController* controller = new controller::DebugController();
|
||||
return controller;
|
||||
}
|
||||
|
||||
template <>
|
||||
controller::items::Giftable* parse<controller::items::Giftable> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Giftable")
|
||||
root = root.front().second;
|
||||
|
||||
// Parse
|
||||
return new controller::items::Giftable();
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
controller::items::Weapon* parse<controller::items::Weapon> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "Weapon")
|
||||
root = root.front().second;
|
||||
|
||||
// Parse
|
||||
controller::items::Weapon* weapon = new controller::items::Weapon();
|
||||
weapon->damage = root.get<float>("<xmlattr>.damage");
|
||||
weapon->critProbability = root.get<float>("<xmlattr>.critProbability");
|
||||
weapon->critDamage = root.get<float>("<xmlattr>.critDamage");
|
||||
weapon->attackDuration = root.get<float>("<xmlattr>.attackDuration");
|
||||
return weapon;
|
||||
}
|
||||
|
||||
template <>
|
||||
controller::player::PlayerController* parse<controller::player::PlayerController> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the scene node (property tree seems to add root of its own)
|
||||
if (root.front().first == "PlayerController")
|
||||
root = root.front().second;
|
||||
|
||||
controller::player::PlayerController* controller = new controller::player::PlayerController();
|
||||
return controller;
|
||||
}
|
||||
|
||||
|
||||
/****** Graphics namespace ******/
|
||||
|
||||
template <>
|
||||
graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the 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<graphics::SpriteRenderer> (boost::property_tree::ptree& root)
|
||||
{
|
||||
// Ensure we are on the 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();
|
||||
|
||||
// Load sprite
|
||||
std::string spritePath = root.get<std::string>("<xmlattr>.sprite");
|
||||
resources::ResourceId spriteId = resources::ResourceManager::instance().getId(spritePath);
|
||||
renderer->sprite = parse<base::Sprite>(spriteId);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user