Implemented some tools. Also, implemented inventory.

This commit is contained in:
2016-12-03 19:43:28 +02:00
parent 91c0da855b
commit 0dc77aacb4
38 changed files with 1713 additions and 654 deletions

View File

@@ -14,26 +14,29 @@ namespace assets {
/**
* Maps tiles to ground name
*/
enum class Ground
enum Ground
{
Dirt = 0,
DirtVariation0 = 1,
DirtVariation1 = 2,
DirtVariation2 = 3,
DirtVariation3 = 4,
DirtVariation4 = 5,
DirtVariation5 = 6,
DirtVariation6 = 7,
DirtVariation7 = 8,
DirtVariation8 = 9,
None = 0,
Dirt = 1,
DirtVariation0 = 2,
DirtVariation1 = 3,
DirtVariation2 = 4,
DirtVariation3 = 5,
DirtVariation4 = 6,
DirtVariation5 = 7,
DirtVariation6 = 8,
DirtVariation7 = 9,
DirtVariation8 = 10,
SoilCenter = 30,
SoilDry = 92,
SoilWet = 36
SoilWet = 98,
Water = 180,
};
inline bool groundIsDirt(int cell) { return cell >= Ground::Dirt && cell <= Ground::DirtVariation8; }
inline bool groundIsDrySoil(int cell) { return cell == Ground::SoilCenter; }
inline bool groundIsDrySoil(int cell) { return cell == Ground::SoilDry; }
inline bool groundIsWetSoil(int cell) { return cell == Ground::SoilWet; }
}

View File

@@ -0,0 +1,43 @@
/*
* Axe.cpp
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#include <components/items/Axe.h>
#include <model/Direction.h>
#include <iostream>
namespace farmlands {
namespace components {
namespace items {
Axe::Axe()
{
}
Axe::~Axe()
{
}
model::Component* Axe::clone()
{
return new Axe();
}
void Axe::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Axe\n";
}
void Axe::performAction(float x, float y, model::Direction d)
{
}
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */

View File

@@ -0,0 +1,34 @@
/*
* Axe.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_ITEMS_AXE_H_
#define COMPONENTS_ITEMS_AXE_H_
#include <components/items/ITool.h>
#include <model/Component.h>
namespace farmlands {
namespace components {
namespace items {
class Axe: public model::Component, public ITool
{
public:
Axe();
virtual ~Axe();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void performAction(float x, float y, model::Direction d) override;
};
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_ITEMS_AXE_H_ */

View File

@@ -26,15 +26,8 @@ model::Component* Giftable::clone()
return new Giftable();
}
bool Giftable::canGift(float x, float y, model::Direction d)
void Giftable::performAction(float x, float y, model::Direction d)
{
// TODO: implement Giftable::canGift
return false;
}
void Giftable::offerGift(float x, float y, model::Direction d)
{
// TODO: implement Giftable::offerGift
}
void Giftable::dump(unsigned level)

View File

@@ -8,14 +8,14 @@
#ifndef CONTROLLER_ITEMS_GIFTABLE_H_
#define CONTROLLER_ITEMS_GIFTABLE_H_
#include <components/items/ITool.h>
#include <model/Component.h>
#include <model/Direction.h>
namespace farmlands {
namespace components {
namespace items {
class Giftable: public model::Component
class Giftable: public model::Component, public ITool
{
public:
Giftable();
@@ -24,8 +24,7 @@ namespace items {
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
bool canGift(float x, float y, model::Direction d);
void offerGift(float x, float y, model::Direction d);
virtual void performAction(float x, float y, model::Direction d) override;
};
} /* namespace items */

View File

@@ -5,15 +5,23 @@
* Author: tibi
*/
#include <GameState.h>
#include <assets/Ground.h>
#include <components/items/Hoe.h>
#include <math/GameMath.h>
#include <model/GameObject.h>
#include <model/Scene.h>
#include <iostream>
using namespace farmlands::assets;
namespace farmlands {
namespace components {
namespace items {
Hoe::Hoe()
: m_back(nullptr)
{
}
@@ -34,8 +42,34 @@ void Hoe::dump(unsigned level)
std::cout << " .Component: Hoe\n";
}
void Hoe::performAttack(float x, float y, model::Direction d)
void Hoe::onInitialize()
{
model::GameObject* root = &GameState::current().scene->root;
// Find background object
auto it = root->findByComponent<Background>();
Assert(it != root->childrenEnd(), "Can't find background game object.");
m_back = (*it)->component<Background>();
}
void Hoe::performAction(float x, float y, model::Direction d)
{
Assert(m_back, "No background object!!!");
// Compute watering position
float digX, digY;
translate(x, y, d, 0.5f, &digX, &digY);
size_t col = floorf(digX);
size_t row = floorf(digY);
// See what the cell contains
Cell backCell = m_back->cell(0, row, col);
Cell soilCell = m_back->cell(1, row, col);
if (groundIsDirt(backCell) && soilCell == Ground::None)
m_back->setCell(1, row, col, Ground::SoilDry);
}
} /* namespace items */

View File

@@ -8,6 +8,8 @@
#ifndef COMPONENTS_ITEMS_HOE_H_
#define COMPONENTS_ITEMS_HOE_H_
#include <components/Background.h>
#include <components/items/ITool.h>
#include <model/Component.h>
#include <model/Direction.h>
@@ -15,7 +17,7 @@ namespace farmlands {
namespace components {
namespace items {
class Hoe: public model::Component
class Hoe: public model::Component, public ITool
{
public:
Hoe();
@@ -24,7 +26,12 @@ namespace items {
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
void performAttack(float x, float y, model::Direction d);
virtual void onInitialize() override;
virtual void performAction(float x, float y, model::Direction d) override;
private:
Background* m_back;
};
} /* namespace items */

View File

@@ -0,0 +1,28 @@
/*
* ITool.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_ITEMS_ITOOL_H_
#define COMPONENTS_ITEMS_ITOOL_H_
#include <model/Direction.h>
namespace farmlands {
namespace components {
namespace items {
class ITool
{
public:
virtual ~ITool() { }
virtual void performAction(float playerX, float playerY, model::Direction) = 0;
};
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_ITEMS_ITOOL_H_ */

View File

@@ -0,0 +1,43 @@
/*
* Pickaxe.cpp
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#include <components/items/Pickaxe.h>
#include <iostream>
namespace farmlands {
namespace components {
namespace items {
Pickaxe::Pickaxe()
{
}
Pickaxe::~Pickaxe()
{
}
model::Component* Pickaxe::clone()
{
return new Pickaxe();
}
void Pickaxe::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Pickaxe\n";
}
void Pickaxe::performAction(float x, float y, model::Direction d)
{
}
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */

View File

@@ -0,0 +1,34 @@
/*
* Pickaxe.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_ITEMS_PICKAXE_H_
#define COMPONENTS_ITEMS_PICKAXE_H_
#include <components/items/ITool.h>
#include <model/Component.h>
namespace farmlands {
namespace components {
namespace items {
class Pickaxe: public model::Component, public ITool
{
public:
Pickaxe();
virtual ~Pickaxe();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void performAction(float x, float y, model::Direction d) override;
};
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_ITEMS_PICKAXE_H_ */

View File

@@ -0,0 +1,43 @@
/*
* Scythe.cpp
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#include <components/items/Scythe.h>
#include <model/Direction.h>
#include <iostream>
namespace farmlands {
namespace components {
namespace items {
Scythe::Scythe()
{
}
Scythe::~Scythe()
{
}
model::Component* Scythe::clone()
{
return new Scythe();
}
void Scythe::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Scythe\n";
}
void Scythe::performAction(float x, float y, model::Direction d)
{
}
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */

View File

@@ -0,0 +1,34 @@
/*
* Scythe.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_ITEMS_SCYTHE_H_
#define COMPONENTS_ITEMS_SCYTHE_H_
#include <components/items/ITool.h>
#include <model/Component.h>
namespace farmlands {
namespace components {
namespace items {
class Scythe: public model::Component, public ITool
{
public:
Scythe();
virtual ~Scythe();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void performAction(float x, float y, model::Direction d) override;
};
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_ITEMS_SCYTHE_H_ */

View File

@@ -0,0 +1,95 @@
/*
* WateringCan.cpp
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#include <GameState.h>
#include <assets/Ground.h>
#include <components/items/WateringCan.h>
#include <math/GameMath.h>
#include <utils/Assert.h>
#include <iostream>
using namespace farmlands::assets;
namespace farmlands {
namespace components {
namespace items {
WateringCan::WateringCan()
: capacity(10),
amountLeft(10),
m_back(nullptr)
{
}
WateringCan::~WateringCan()
{
}
model::Component* WateringCan::clone()
{
WateringCan* clone = new WateringCan();
clone->capacity = capacity;
clone->amountLeft = amountLeft;
return clone;
}
void WateringCan::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Hoe\n";
}
void WateringCan::onInitialize()
{
model::GameObject* root = &GameState::current().scene->root;
// Find background object
auto it = root->findByComponent<Background>();
Assert(it != root->childrenEnd(), "Can't find background game object.");
m_back = (*it)->component<Background>();
}
void WateringCan::performAction(float x, float y, model::Direction d)
{
Assert(m_back, "No background object!!!");
// Compute watering position
float digX, digY;
translate(x, y, d, 0.5f, &digX, &digY);
size_t col = floorf(digX);
size_t row = floorf(digY);
// See what the cell contains
Cell backCell = m_back->cell(0, row, col);
Cell soilCell = m_back->cell(1, row, col);
// If there is water, fill can
if (backCell == Ground::Water)
{
amountLeft = capacity;
std::cout << "Filled can: " << amountLeft << "\n";
}
// If there is dry soil, wet it
if (groundIsDrySoil(soilCell) && amountLeft > 0)
{
m_back->setCell(1, row, col, Ground::SoilWet);
--amountLeft;
std::cout << "Watering can: " << amountLeft << "\n";
}
}
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */

View File

@@ -0,0 +1,45 @@
/*
* WateringCan.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_ITEMS_WATERINGCAN_H_
#define COMPONENTS_ITEMS_WATERINGCAN_H_
#include <components/Background.h>
#include <components/items/ITool.h>
#include <model/Component.h>
#include <model/Direction.h>
namespace farmlands {
namespace components {
namespace items {
class WateringCan: public model::Component, public ITool
{
public:
WateringCan();
virtual ~WateringCan();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override;
virtual void performAction(float x, float y, model::Direction d) override;
public:
uint32_t capacity;
uint32_t amountLeft;
private:
Background* m_back;
};
} /* namespace items */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_ITEMS_WATERINGCAN_H_ */

View File

@@ -57,7 +57,7 @@ void Weapon::onUpdateLogic()
}
}
void Weapon::performAttack(float x, float y, model::Direction d)
void Weapon::performAction(float x, float y, model::Direction d)
{
if (attackTimeLeft <= 0)
{
@@ -70,7 +70,7 @@ void Weapon::dump(unsigned level)
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: Transform ";
std::cout << " .Component: Weapon ";
std::cout << "damage="<<damage<<" ";
std::cout << "critProbability="<<critProbability<<" ";
std::cout << "critDamage="<<critDamage<<" ";

View File

@@ -9,15 +9,15 @@
#define CONTROLLER_ITEMS_WEAPON_H_
#include <components/basic/Sprite.h>
#include <components/items/ITool.h>
#include <graphics/SpriteRenderer.h>
#include <model/Component.h>
#include <model/Direction.h>
namespace farmlands {
namespace components {
namespace items {
class Weapon: public model::Component
class Weapon: public model::Component, public ITool
{
public:
Weapon();
@@ -33,7 +33,7 @@ namespace items {
/**
* Performs everything required to attacking an enemy with a weapon. To be called from player controller.
*/
void performAttack(float x, float y, model::Direction d);
virtual void performAction(float x, float y, model::Direction d);
// Properties
float damage;

View File

@@ -1,235 +0,0 @@
/*
* PlayerController.cpp
*
* Created on: Nov 27, 2016
* Author: tibi
*/
#include <GameState.h>
#include <components/items/Giftable.h>
#include <components/items/Hoe.h>
#include <components/items/Item.h>
#include <components/items/Weapon.h>
#include <components/player/PlayerController.h>
#include <graphics/SpriteRenderer.h>
#include <input/Input.h>
#include <utils/Assert.h>
#include <iostream>
using namespace farmlands::components::basic;
using namespace farmlands::components::items;
using namespace farmlands::graphics;
using namespace farmlands::input;
using namespace farmlands::model;
namespace farmlands {
namespace components {
namespace player {
static const float PlayerWalkVelocity = 2.0f; // The default velocity of the player when walking (units/sec).
static const float PlayerRunVelocity = 4.0f; // The default velocity of the player when running (units/sec).
static const float PlayerAttackVelocity = 0.1f; // Movement speed when attacking.
/**
* Direction enum based on sign of velocity on x and y
*/
static const Direction VelocitySignDirections[3][3] =
{
{ Direction::NorthWest, Direction::West, Direction::SouthWest },
{ Direction::North, Direction::None, Direction::South },
{ Direction::NorthEast, Direction::East, Direction::SouthEast },
};
PlayerController::PlayerController()
: m_transform(nullptr),
m_facingDirection(Direction::South),
m_walking(false),
m_running(false),
m_currentItem(nullptr),
m_currentWeapon(nullptr)
{
}
PlayerController::~PlayerController()
{
}
model::Component* PlayerController::clone()
{
return new PlayerController();
}
void PlayerController::onInitialize()
{
m_transform = gameObject->component<components::basic::Transform>();
}
bool PlayerController::onEvent(SDL_Event& event)
{
handleAttackEvents(event);
handleInventoryEvents(event);
return false;
}
void PlayerController::handleAttackEvents(SDL_Event& event)
{
bool attack = (Input::instance().down(GameKey::Action, event));
if (attack && m_currentItem != nullptr)
{
// Weapon behavior
Weapon* weapon = m_currentItem->component<Weapon>();
if (weapon)
weapon->performAttack(m_transform->x, m_transform->y, m_facingDirection);
// Tools
Hoe* hoe = m_currentItem->component<Hoe>();
if (hoe)
hoe->performAttack(m_transform->x, m_transform->y, m_facingDirection);
// Gift behavior
Giftable* giftable = m_currentItem->component<Giftable>();
if (giftable)
giftable->offerGift(m_transform->x, m_transform->y, m_facingDirection);
}
}
void PlayerController::handleInventoryEvents(SDL_Event& event)
{
// See what key was pressed
int slot = -1;
if (Input::instance().down(GameKey::Inventory1, event)) slot = 1;
if (Input::instance().down(GameKey::Inventory2, event)) slot = 2;
if (Input::instance().down(GameKey::Inventory3, event)) slot = 3;
if (Input::instance().down(GameKey::Inventory4, event)) slot = 4;
if (Input::instance().down(GameKey::Inventory5, event)) slot = 5;
if (Input::instance().down(GameKey::Inventory6, event)) slot = 6;
if (Input::instance().down(GameKey::Inventory7, event)) slot = 7;
if (Input::instance().down(GameKey::Inventory8, event)) slot = 8;
if (Input::instance().down(GameKey::Inventory9, event)) slot = 9;
if (Input::instance().down(GameKey::Inventory10, event)) slot = 10;
// For now we don't have an inventory, so just instantiate some object
if (0 <= slot && slot <= GameState::current().itemPrefabs.size())
{
GameObject* itemPrefab = GameState::current().itemPrefabs[slot - 1];
// Get rid of old object
if (m_currentItem != nullptr)
gameObject->destroyChild(m_currentItem);
// Instantiate new object
m_currentItem = GameObject::instantiate(itemPrefab, "Current item", gameObject);
m_currentWeapon = m_currentItem->component<Weapon>();
}
else if (0 <= slot)
{
std::cout << "Slot " << slot << "empty\n";
}
}
void PlayerController::onUpdateLogic()
{
m_running = false;
m_walking = false;
// Compute movement velocity
float velMultiplier = PlayerWalkVelocity;
if (m_currentWeapon && m_currentWeapon->attackTimeLeft > 0)
{
velMultiplier = PlayerAttackVelocity;
}
else if (Input::instance().pressed(GameKey::Run))
{
velMultiplier = PlayerRunVelocity;
m_running = true;
}
// Make movement time independent
velMultiplier *= GameState::current().elapsedTime;
// Get velocity of axes
float vx = Input::instance().getX() * velMultiplier;
float vy = Input::instance().getY() * velMultiplier;
// Check if we can move to the new position
float newX = m_transform->x + vx;
float newY = m_transform->y + vy;
if ((vx || vy) && canMove(newX, newY))
{
m_walking = true;
m_transform->x = newX;
m_transform->y = newY;
m_facingDirection = getDirection(vx, vy);
}
}
void PlayerController::onPreRender()
{
// Get sprite
Sprite* sprite = gameObject->component<Sprite>();
// Compute current state
std::string stateName = (m_walking) ? "Walking " : "Idle ";
if (m_facingDirection & Direction::East)
stateName += "right";
else if (m_facingDirection & Direction::West)
stateName += "left";
else if (m_facingDirection & Direction::North)
stateName += "up";
else
stateName += "down";
sprite->setState(stateName);
// Set animation velocity
float animVelocity = (m_running) ? 1.0f : 0.7f;
if (m_currentWeapon && m_currentWeapon->attackTimeLeft > 0)
animVelocity = 0.1f;
sprite->animationVelocity = animVelocity;
// Set weapon
if (m_currentItem)
{
Transform* itemTransf = m_currentItem->component<Transform>();
itemTransf->x = 0.2f;
itemTransf->y = -0.8f;
}
// Set camera
components::basic::Transform* cam = GameState::current().renderContext.cameraTransform();
cam->x = m_transform->x;
cam->y = m_transform->y - 1;
}
bool PlayerController::canMove(float x, float y)
{
// TODO: check collisions & stuff. For now, nothing
return true;
}
Direction PlayerController::getDirection(float vx, float vy)
{
int xx = (0 < vx) - (vx < 0);
int yy = (0 < vy) - (vy < 0);
return VelocitySignDirections[xx + 1][yy + 1];
}
void PlayerController::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: PlayerController\n";
}
}
} /* namespace controller */
} /* namespace farmlands */

View File

@@ -0,0 +1,173 @@
/*
* PlayerInventory.cpp
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#include <GameState.h>
#include <components/items/Weapon.h>
#include <components/player/PlayerInventory.h>
#include <components/player/PlayerMovement.h>
#include <input/Input.h>
#include <model/GameObject.h>
#include <iostream>
using namespace farmlands::components::basic;
using namespace farmlands::components::items;
using namespace farmlands::graphics;
using namespace farmlands::input;
using namespace farmlands::model;
namespace farmlands {
namespace components {
namespace player {
PlayerInventory::PlayerInventory()
: capacity(10),
currentItemIndex(-1),
currentItem(nullptr),
currentWeapon(nullptr),
m_inventory(nullptr),
m_playerTransform(nullptr),
m_playerMovement(nullptr)
{
}
PlayerInventory::~PlayerInventory()
{
}
model::Component* PlayerInventory::clone()
{
PlayerInventory* clone = new PlayerInventory();
clone->capacity = capacity;
clone->currentItemIndex = currentItemIndex;
return clone;
}
void PlayerInventory::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: PlayerInventory\n";
}
void PlayerInventory::onInitialize()
{
// Get component named "Inventory" (create it if it doesn't exist)
auto it = gameObject->findByName("Inventory");
if (it == gameObject->childrenEnd())
{
m_inventory = new model::GameObject();
m_inventory->name = "Inventory";
gameObject->addChild(m_inventory);
gameObject->addComponent(new Transform());
m_inventory->onCreate();
}
else
{
m_inventory = *it;
}
// Get current item
if (0 <= currentItemIndex && currentItemIndex < (int)m_inventory->childrenSize())
{
currentItem = *(m_inventory->childrenBegin() + currentItemIndex);
currentWeapon = currentItem->component<Weapon>();
}
// Ensure all items except current item are disabled
for (auto it = m_inventory->childrenBegin(); it != m_inventory->childrenEnd(); it++)
(*it)->setEnabled(*it == currentItem);
// Get transform
m_playerTransform = gameObject->component<Transform>();
m_playerMovement = gameObject->component<PlayerMovement>();
}
bool PlayerInventory::onEvent(SDL_Event& event)
{
handleAttackEvents(event);
handleInventoryEvents(event);
return false;
}
void PlayerInventory::onUpdateLogic()
{
}
void PlayerInventory::onPreRender()
{
// Set item position
if (currentItem)
{
Transform* itemTransf = currentItem->component<Transform>();
itemTransf->x = 0.2f;
itemTransf->y = -0.8f;
}
}
void PlayerInventory::handleAttackEvents(SDL_Event& event)
{
bool attack = Input::instance().down(GameKey::Action, event);
if (attack && currentItem != nullptr)
{
float x = m_playerTransform->x;
float y = m_playerTransform->y;
Direction d = m_playerMovement->facingDirection;
// Call components which implement ITool
for (auto it = currentItem->componentsBegin(); it != currentItem->componentsEnd(); it++)
{
ITool* tool = dynamic_cast<ITool*>(it->second);
if (tool != nullptr)
tool->performAction(x, y, d);
}
}
}
void PlayerInventory::handleInventoryEvents(SDL_Event& event)
{
// See what key was pressed
int slot = -1;
if (Input::instance().down(GameKey::Inventory1, event)) slot = 0;
if (Input::instance().down(GameKey::Inventory2, event)) slot = 1;
if (Input::instance().down(GameKey::Inventory3, event)) slot = 2;
if (Input::instance().down(GameKey::Inventory4, event)) slot = 3;
if (Input::instance().down(GameKey::Inventory5, event)) slot = 4;
if (Input::instance().down(GameKey::Inventory6, event)) slot = 5;
if (Input::instance().down(GameKey::Inventory7, event)) slot = 6;
if (Input::instance().down(GameKey::Inventory8, event)) slot = 7;
if (Input::instance().down(GameKey::Inventory9, event)) slot = 8;
if (Input::instance().down(GameKey::Inventory10, event)) slot = 9;
if (0 <= slot && slot < (int)m_inventory->childrenSize())
{
// Disable old object
if (currentItem != nullptr)
currentItem->setEnabled(false);
// Obtain new object
currentItemIndex = slot;
currentItem = *(m_inventory->childrenBegin() + slot);
currentWeapon = currentItem->component<Weapon>();
// Enable new object
currentItem->setEnabled(true);
gameObject->dumpTree(0);
}
else if (0 <= slot)
{
std::cout << "Slot " << slot << "empty\n";
}
}
} /* namespace player */
} /* namespace components */
} /* namespace farmlands */

View File

@@ -0,0 +1,59 @@
/*
* PlayerInventory.h
*
* Created on: Dec 3, 2016
* Author: tibi
*/
#ifndef COMPONENTS_PLAYER_PLAYERINVENTORY_H_
#define COMPONENTS_PLAYER_PLAYERINVENTORY_H_
#include <components/basic/Transform.h>
#include <components/items/Weapon.h>
#include <model/Component.h>
namespace farmlands {
namespace components {
namespace player {
class PlayerMovement;
class PlayerInventory: public model::Component
{
public:
PlayerInventory();
virtual ~PlayerInventory();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override;
virtual bool onEvent(SDL_Event& event) override;
virtual void onUpdateLogic() override;
virtual void onPreRender() override;
uint32_t capacity;
// Current item
int currentItemIndex;
model::GameObject* currentItem;
items::Weapon* currentWeapon;
private:
void handleAttackEvents(SDL_Event& event);
void handleInventoryEvents(SDL_Event& event);
// Inventory
model::GameObject* m_inventory;
// Player transform
basic::Transform* m_playerTransform;
PlayerMovement* m_playerMovement;
};
} /* namespace player */
} /* namespace components */
} /* namespace farmlands */
#endif /* COMPONENTS_PLAYER_PLAYERINVENTORY_H_ */

View File

@@ -0,0 +1,160 @@
/*
* PlayerMovement.cpp
*
* Created on: Nov 27, 2016
* Author: tibi
*/
#include <GameState.h>
#include <components/items/Item.h>
#include <components/items/Weapon.h>
#include <components/player/PlayerInventory.h>
#include <components/player/PlayerMovement.h>
#include <graphics/SpriteRenderer.h>
#include <input/Input.h>
#include <utils/Assert.h>
#include <iostream>
using namespace farmlands::components::basic;
using namespace farmlands::components::items;
using namespace farmlands::graphics;
using namespace farmlands::input;
using namespace farmlands::model;
namespace farmlands {
namespace components {
namespace player {
static const float PlayerWalkVelocity = 2.0f; // The default velocity of the player when walking (units/sec).
static const float PlayerRunVelocity = 4.0f; // The default velocity of the player when running (units/sec).
static const float PlayerAttackVelocity = 0.1f; // Movement speed when attacking.
/**
* Direction enum based on sign of velocity on x and y
*/
static const Direction VelocitySignDirections[3][3] =
{
{ Direction::NorthWest, Direction::West, Direction::SouthWest },
{ Direction::North, Direction::None, Direction::South },
{ Direction::NorthEast, Direction::East, Direction::SouthEast },
};
PlayerMovement::PlayerMovement()
: facingDirection(Direction::South),
walking(false),
running(false),
m_transform(nullptr),
m_inventory(nullptr)
{
}
PlayerMovement::~PlayerMovement()
{
}
model::Component* PlayerMovement::clone()
{
PlayerMovement* clone = new PlayerMovement();
clone->facingDirection = facingDirection;
return clone;
}
void PlayerMovement::onInitialize()
{
m_transform = gameObject->component<components::basic::Transform>();
m_inventory = gameObject->component<PlayerInventory>();
}
void PlayerMovement::onUpdateLogic()
{
running = Input::instance().pressed(GameKey::Run);
walking = false;
// Compute movement velocity
float velMultiplier = PlayerWalkVelocity;
if (m_inventory->currentWeapon && m_inventory->currentWeapon->attackTimeLeft > 0)
velMultiplier = PlayerAttackVelocity;
else if (running)
velMultiplier = PlayerRunVelocity;
// Make movement time independent
velMultiplier *= GameState::current().elapsedTime;
// Get velocity of axes
float vx = Input::instance().getX() * velMultiplier;
float vy = Input::instance().getY() * velMultiplier;
// Check if we can move to the new position
float newX = m_transform->x + vx;
float newY = m_transform->y + vy;
if ((vx || vy) && canMove(newX, newY))
{
walking = true;
m_transform->x = newX;
m_transform->y = newY;
facingDirection = getDirection(vx, vy);
}
}
void PlayerMovement::onPreRender()
{
// Get sprite
Sprite* sprite = gameObject->component<Sprite>();
// Compute current state
std::string stateName = (walking) ? "Walking " : "Idle ";
if (facingDirection & Direction::East)
stateName += "right";
else if (facingDirection & Direction::West)
stateName += "left";
else if (facingDirection & Direction::North)
stateName += "up";
else
stateName += "down";
sprite->setState(stateName);
// Set animation velocity
float animVelocity = (running) ? 1.0f : 0.7f;
if (m_inventory->currentWeapon && m_inventory->currentWeapon->attackTimeLeft > 0)
animVelocity = 0.1f;
// TODO: move this animation velocity change somewhere else
sprite->animationVelocity = animVelocity;
// Set camera
components::basic::Transform* cam = GameState::current().renderContext.cameraTransform();
cam->x = m_transform->x;
cam->y = m_transform->y - 1;
}
bool PlayerMovement::canMove(float x, float y)
{
// TODO: check collisions & stuff. For now, nothing
return true;
}
Direction PlayerMovement::getDirection(float vx, float vy)
{
int xx = (0 < vx) - (vx < 0);
int yy = (0 < vy) - (vy < 0);
return VelocitySignDirections[xx + 1][yy + 1];
}
void PlayerMovement::dump(unsigned level)
{
for (unsigned i = 0; i < level; i++)
std::cout<<" ";
std::cout << " .Component: PlayerMovement\n";
}
}
} /* namespace controller */
} /* namespace farmlands */

View File

@@ -15,39 +15,39 @@
#include <SDL2/SDL.h>
#define MAX_INVENTORY_SIZE 50
namespace farmlands {
namespace components {
namespace player {
class PlayerController : public model::Component
class PlayerInventory;
class PlayerMovement : public model::Component
{
public:
PlayerController();
virtual ~PlayerController();
PlayerMovement();
virtual ~PlayerMovement();
virtual model::Component* clone() override;
virtual void dump(unsigned level) override;
virtual void onInitialize() override;
virtual bool onEvent(SDL_Event& event) override;
virtual void onUpdateLogic() override;
virtual void onPreRender() override;
model::Direction facingDirection;
bool walking, running;
private:
static model::Direction getDirection(float vx, float vy);
void handleAttackEvents(SDL_Event& event);
void handleInventoryEvents(SDL_Event& event);
bool canMove(float x, float y);
// Movement
basic::Transform* m_transform;
model::Direction m_facingDirection;
bool m_walking, m_running;
model::GameObject* m_currentItem;
items::Weapon* m_currentWeapon;
// For getting speed
PlayerInventory* m_inventory;
};
}

View File

@@ -7,4 +7,33 @@
#include <math/GameMath.h>
namespace farmlands {
static const float Sqrt2 = 1.41421356237309504880f;
static const float DirectionVectorX[] =
{
0, 1, 0, Sqrt2, // none, E, N, NE
-1, 0, -Sqrt2, 0, // W, inv, NW, inv
0, Sqrt2, 0, 0, // S, SE, inv, inv
-Sqrt2, 0, 0, 0 // SW, inv, inv, inv
};
static const float DirectionVectorY[] =
{
0, 0, -1, -Sqrt2, // none, E, N, NE
0, 0, -Sqrt2, 0, // W, inv, NW, inv
1, Sqrt2, 0, 0, // S, SE, inv, inv
Sqrt2, 0, 0, 0 // SW, inv, inv, inv
};
void translate(float x, float y, model::Direction direction, float distance, float* outX, float *outY)
{
float dx = DirectionVectorX[direction];
float dy = DirectionVectorY[direction];
*outX = x + dx * distance;
*outY = y + dy * distance;
}
}

View File

@@ -8,18 +8,23 @@
#ifndef MATH_GAMEMATH_H_
#define MATH_GAMEMATH_H_
template<typename TVal, typename TMin, typename TMax>
TVal clamp (TVal value, TMin min, TMax max)
{
if (value < min)
return min;
#include <model/Direction.h>
if (value > max)
return max;
namespace farmlands {
template<typename TVal, typename TMin, typename TMax>
TVal clamp (TVal value, TMin min, TMax max)
{
if (value < min)
return min;
if (value > max)
return max;
return value;
}
void translate(float x, float y, model::Direction direction, float distance, float* outX, float *outY);
return value;
}
#endif /* MATH_GAMEMATH_H_ */

View File

@@ -81,13 +81,28 @@ GameObject* GameObject::instantiate(GameObject* gameObject, std::string name, Ga
return instance;
}
size_t GameObject::componentsSize() const
{
return m_components.size();
}
GameObject::ComponentIterator GameObject::componentsBegin()
{
return m_components.begin();
}
GameObject::ComponentIterator GameObject::componentsEnd()
{
return m_components.end();
}
void GameObject::addChild(GameObject* obj)
{
m_children.push_back(obj);
obj->m_parent = this;
}
GameObject* GameObject::removeChild(GameObject::iterator it)
GameObject* GameObject::removeChild(GameObject::ChildrenIterator it)
{
m_children.erase(it);
return *it;
@@ -107,7 +122,7 @@ GameObject* GameObject::removeChild(GameObject* obj)
return nullptr;
}
void GameObject::destroyChild(GameObject::iterator it)
void GameObject::destroyChild(GameObject::ChildrenIterator it)
{
delete *it;
m_children.erase(it);
@@ -131,12 +146,12 @@ size_t GameObject::childrenSize() const
return m_children.size();
}
GameObject::iterator GameObject::childrenBegin()
GameObject::ChildrenIterator GameObject::childrenBegin()
{
return m_children.begin();
}
GameObject::iterator GameObject::childrenEnd()
GameObject::ChildrenIterator GameObject::childrenEnd()
{
return m_children.end();
}
@@ -146,6 +161,20 @@ GameObject* GameObject::parent()
return m_parent;
}
GameObject::ChildrenIterator GameObject::findByName(std::string name)
{
return findByName(name, childrenBegin());
}
GameObject::ChildrenIterator GameObject::findByName(std::string name, ChildrenIterator begin)
{
for (auto it = begin; it != childrenEnd(); it++)
if ((*it)->name == name)
return it;
return childrenEnd();
}
void GameObject::onCreate()
{
// Enable self
@@ -303,3 +332,4 @@ void GameObject::dumpTree(unsigned level)
} /* namespace model */
} /* namespace farmlands */

View File

@@ -27,7 +27,11 @@ namespace model {
class GameObject : public INonAssignable, public ICloneable<GameObject>
{
public:
typedef std::vector<GameObject*>::iterator iterator;
typedef std::unordered_map<std::type_index, Component*> ComponentContainer;
typedef std::vector<GameObject*> ChildrenContainer;
typedef ComponentContainer::iterator ComponentIterator;
typedef ChildrenContainer::iterator ChildrenIterator;
// Constructors
GameObject();
@@ -40,21 +44,36 @@ namespace model {
template <typename T> T* component();
template <typename T> bool haveComponent();
template <typename T> void addComponent(T* component);
template <typename T> void removeComponent();
template <typename T> T* removeComponent();
template <typename T> void destroyComponent();
size_t componentsSize() const;
ComponentIterator componentsBegin();
ComponentIterator componentsEnd();
// Tree methods
void addChild(GameObject* obj);
GameObject* removeChild(iterator it);
GameObject* removeChild(ChildrenIterator it);
GameObject* removeChild(GameObject* obj);
void destroyChild(iterator it);
void destroyChild(ChildrenIterator it);
void destroyChild(GameObject* obj);
size_t childrenSize() const;
iterator childrenBegin();
iterator childrenEnd();
ChildrenIterator childrenBegin();
ChildrenIterator childrenEnd();
GameObject* parent();
// Search method
ChildrenIterator findByName(std::string name);
ChildrenIterator findByName(std::string name, ChildrenIterator begin);
template <typename T>
ChildrenIterator findByComponent();
template <typename T>
ChildrenIterator findByComponent(ChildrenIterator begin);
// Game object methods
void onCreate();
void onInitialize();
@@ -81,10 +100,10 @@ namespace model {
private:
// Components
std::unordered_map<std::type_index, Component*> m_components;
ComponentContainer m_components;
// Tree
std::vector<GameObject*> m_children;
ChildrenContainer m_children;
GameObject* m_parent;
// Properties
@@ -131,10 +150,42 @@ namespace model {
}
template <typename T>
void GameObject::removeComponent()
T* GameObject::removeComponent()
{
std::type_index typeIndex(typeid(T));
return m_components.erase(typeIndex);
T* comp = nullptr;
auto it = m_components.find(typeIndex);
if (it != m_components.end())
{
comp = it->second;
m_components.erase(it);
}
return comp;
}
template <typename T>
void GameObject::destroyComponent()
{
std::type_index typeIndex(typeid(T));
m_components.erase(typeIndex);
}
template <typename T>
GameObject::ChildrenIterator GameObject::findByComponent()
{
return findByComponent<T>(childrenBegin());
}
template <typename T>
GameObject::ChildrenIterator GameObject::findByComponent(GameObject::ChildrenIterator begin)
{
for (auto it = begin; it != childrenEnd(); it++)
if ((*it)->haveComponent<T>())
return it;
return childrenEnd();
}
} /* namespace model */

View File

@@ -7,6 +7,7 @@
#include <GameState.h>
#include <graphics/backend/SdlRenderer.h>
#include <model/GameObject.h>
#include <resources/ResourceManager.h>
#include <resources/Resources.h>
#include <storage/Parsers.h>
@@ -85,6 +86,15 @@ void ResourceManager::loadGame()
storage::parseCollection(R::Items::Tools, GameState::current().itemPrefabs);
storage::parseCollection(R::Items::Weapons, GameState::current().itemPrefabs);
// Get to "Inventory" object
model::GameObject* root = &GameState::current().scene->root;
model::GameObject* player = *root->findByName("Player");
model::GameObject* inventory = *player->findByName("Inventory");
// Give player all items
for (auto prefab : GameState::current().itemPrefabs)
model::GameObject::instantiate(prefab, "inv item", inventory);
}
std::string ResourceManager::getPath(ResourceId resourceId)

View File

@@ -15,65 +15,70 @@ namespace resources {
enum Sprites
{
Player = 0,
items_Lvl2Sword = 1,
items_Stone_pickaxe = 2,
items_HoeStone = 3,
items_Lvl1Sword = 4,
items_Sword = 5,
items_Hoe = 6,
items_WateringCan = 1,
items_Lvl2Sword = 2,
items_Stone_pickaxe = 3,
items_HoeStone = 4,
items_Lvl1Sword = 5,
items_RustyWateringCan = 6,
items_Sword = 7,
items_Hoe = 8,
};
enum Scenes
{
Game = 7,
Game = 9,
};
enum Fonts
{
DejaVuSans = 8,
DejaVuSans = 10,
};
enum Tilesets
{
PlayerTiles = 9,
Ground = 10,
PlayerTiles = 11,
Ground = 12,
};
enum Ui
{
Mini_inventory = 11,
Cursor = 12,
Mini_inventory = 13,
Cursor = 14,
};
enum Levels
{
Farm_Background = 13,
Farm = 14,
Farm_Background = 15,
Farm = 16,
Farm_Soil = 17,
};
enum Config
{
Default = 15,
Default = 18,
};
enum Items
{
Tools = 16,
Weapons = 17,
Tools = 19,
Weapons = 20,
};
}
const int RInfo_Sprites_Begin = 0;
const int RInfo_Scenes_Begin = 7;
const int RInfo_Fonts_Begin = 8;
const int RInfo_Tilesets_Begin = 9;
const int RInfo_Ui_Begin = 11;
const int RInfo_Levels_Begin = 13;
const int RInfo_Config_Begin = 15;
const int RInfo_Items_Begin = 16;
const int RInfo_Scenes_Begin = 9;
const int RInfo_Fonts_Begin = 10;
const int RInfo_Tilesets_Begin = 11;
const int RInfo_Ui_Begin = 13;
const int RInfo_Levels_Begin = 15;
const int RInfo_Config_Begin = 18;
const int RInfo_Items_Begin = 19;
/**
* This array contains the names of all the files, and the corresponding file type.
*/
const ResourceInfo RInfo[] = {
{ "sprites/Player.sprite", ResourceType::Sprite },
{ "sprites/items/wateringCan.png", ResourceType::Texture },
{ "sprites/items/Lvl2Sword.sprite", ResourceType::Sprite },
{ "sprites/items/stone_pickaxe.sprite", ResourceType::Sprite },
{ "sprites/items/HoeStone.sprite", ResourceType::Sprite },
{ "sprites/items/Lvl1Sword.sprite", ResourceType::Sprite },
{ "sprites/items/RustyWateringCan.sprite", ResourceType::Sprite },
{ "sprites/items/sword.png", ResourceType::Texture },
{ "sprites/items/hoe.png", ResourceType::Texture },
{ "scenes/Game.scene", ResourceType::Scene },
@@ -84,6 +89,7 @@ namespace resources {
{ "ui/cursor.png", ResourceType::Texture },
{ "levels/Farm_Background.csv", ResourceType::BackgroundLayer },
{ "levels/Farm.back", ResourceType::Background },
{ "levels/Farm_Soil.csv", ResourceType::BackgroundLayer },
{ "config/Default.config", ResourceType::Configuration },
{ "items/Tools.items", ResourceType::ItemCollection },
{ "items/Weapons.items", ResourceType::ItemCollection },

View File

@@ -8,12 +8,6 @@
#include <storage/Parsers.h>
#include <resources/Resources.h>
using namespace farmlands::components;
using namespace farmlands::components::basic;
using namespace farmlands::components::items;
using namespace farmlands::components::player;
using namespace farmlands::graphics;
using namespace farmlands::model;
using namespace farmlands::resources;
namespace farmlands {
@@ -21,7 +15,7 @@ namespace storage {
/****** Components ******/
void parseBackgroundCells(resources::ResourceId cellsResource, Background* back, size_t layer)
void parseBackgroundCells(resources::ResourceId cellsResource, components::Background* back, size_t layer)
{
Assert(RInfo[cellsResource].type == ResourceType::BackgroundLayer, "Resource must be a level layer.");
@@ -45,7 +39,7 @@ void parseBackgroundCells(resources::ResourceId cellsResource, Background* back,
char* nextNum = strtok(buffer, ",;");
for (size_t col = 0; col < back->columnCount() && nextNum != NULL; col++)
{
Cell cell = (Cell) strtol(nextNum, NULL, 10);
components::Cell cell = (components::Cell) strtol(nextNum, NULL, 10);
back->setCell(layer, row, col, cell);
nextNum = strtok(NULL, ",;");
@@ -56,9 +50,9 @@ void parseBackgroundCells(resources::ResourceId cellsResource, Background* back,
}
template <>
Background* parse<Background> (boost::property_tree::ptree& root)
components::Background* parse<components::Background> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
@@ -67,7 +61,7 @@ Background* parse<Background> (boost::property_tree::ptree& root)
if (!src.empty())
{
ResourceId id = ResourceManager::instance().getId(src);
return parse<Background>(id);
return parse<components::Background>(id);
}
// Read sizes
@@ -75,8 +69,8 @@ Background* parse<Background> (boost::property_tree::ptree& root)
uint32_t rows = root.get<uint32_t>("<xmlattr>.rows");
uint32_t cols = root.get<uint32_t>("<xmlattr>.columns");
// Create background object
Background* back = new Background(layers, rows, cols);
// Create components::Background object
components::Background* back = new components::Background(layers, rows, cols);
// Read layers
size_t layerNum = 0;
@@ -103,25 +97,25 @@ Background* parse<Background> (boost::property_tree::ptree& root)
}
template <>
Camera* parse<Camera> (boost::property_tree::ptree& root)
components::basic::Camera* parse<components::basic::Camera> (boost::property_tree::ptree& root)
{
if (root.front().first == "Camera")
root = root.front().second;
Camera* camera = new Camera();
components::basic::Camera* camera = new components::basic::Camera();
camera->scale = root.get<float>("<xmlattr>.scale", 1.0f);
camera->mainCamera = root.get<bool>("<xmlattr>.mainCamera", false);
return camera;
}
template <>
Frame* parse<Frame> (boost::property_tree::ptree& root)
components::basic::Frame* parse<components::basic::Frame> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
Frame* frame = new Frame();
components::basic::Frame* frame = new components::basic::Frame();
// Obtine tile set id
std::string tileSetPath = root.get<std::string>("<xmlattr>.tileSet");
@@ -137,9 +131,9 @@ Frame* parse<Frame> (boost::property_tree::ptree& root)
}
template <>
Sprite* parse<Sprite> (boost::property_tree::ptree& root)
components::basic::Sprite* parse<components::basic::Sprite> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
@@ -148,11 +142,11 @@ Sprite* parse<Sprite> (boost::property_tree::ptree& root)
if (!src.empty())
{
ResourceId id = ResourceManager::instance().getId(src);
return parse<Sprite>(id);
return parse<components::basic::Sprite>(id);
}
// Parse sprite
Sprite* sprite = new Sprite();
// Parse components::basic::Sprite
components::basic::Sprite* sprite = new components::basic::Sprite();
sprite->anchorX = root.get<float>("<xmlattr>.anchorX");
sprite->anchorY = root.get<float>("<xmlattr>.anchorY");
sprite->animationVelocity = root.get<float>("<xmlattr>.animationVelocity", 1.0f);
@@ -161,7 +155,7 @@ Sprite* parse<Sprite> (boost::property_tree::ptree& root)
{
if (child.first == "State")
{
SpriteState* state = parse<SpriteState>(child.second);
components::basic::SpriteState* state = parse<components::basic::SpriteState>(child.second);
sprite->addState(*state);
delete state;
}
@@ -171,20 +165,20 @@ Sprite* parse<Sprite> (boost::property_tree::ptree& root)
}
template <>
SpriteState* parse<SpriteState> (boost::property_tree::ptree& root)
components::basic::SpriteState* parse<components::basic::SpriteState> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
SpriteState* spriteState = new SpriteState();
components::basic::SpriteState* spriteState = new components::basic::SpriteState();
spriteState->name = root.get<std::string>("<xmlattr>.name");
for (auto child : root)
{
if (child.first == "Frame")
{
Frame* frame = parse<Frame>(child.second);
components::basic::Frame* frame = parse<components::basic::Frame>(child.second);
spriteState->frames.push_back(*frame);
delete frame;
}
@@ -194,13 +188,13 @@ SpriteState* parse<SpriteState> (boost::property_tree::ptree& root)
}
template <>
Transform* parse<components::basic::Transform> (boost::property_tree::ptree& root)
components::basic::Transform* parse<components::basic::Transform> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
Transform* transform = new Transform();
components::basic::Transform* transform = new components::basic::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);
@@ -210,37 +204,111 @@ Transform* parse<components::basic::Transform> (boost::property_tree::ptree& roo
}
template <>
DebugController* parse<DebugController> (boost::property_tree::ptree& root)
components::DebugController* parse<components::DebugController> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
DebugController* controller = new DebugController();
components::DebugController* controller = new components::DebugController();
return controller;
}
template <>
Giftable* parse<items::Giftable> (boost::property_tree::ptree& root)
components::items::Axe* parse<components::items::Axe> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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<components::items::Giftable> (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 Giftable();
return new components::items::Giftable();
}
template <>
components::items::Hoe* parse<components::items::Hoe> (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<components::items::Item> (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<std::string>("<xmlattr>.name");
item->description = root.get<std::string>("<xmlattr>.description");
item->level = root.get<uint8_t>("<xmlattr>.level");
return item;
}
template <>
Weapon* parse<items::Weapon> (boost::property_tree::ptree& root)
components::items::Pickaxe* parse<components::items::Pickaxe> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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<components::items::Scythe> (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<components::items::WateringCan> (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<float>("<xmlattr>.capacity");
can->amountLeft = root.get<float>("<xmlattr>.amountLeft");
return can;
}
template <>
components::items::Weapon* parse<components::items::Weapon> (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
Weapon* weapon = new Weapon();
components::items::Weapon* weapon = new components::items::Weapon();
weapon->damage = root.get<float>("<xmlattr>.damage");
weapon->critProbability = root.get<float>("<xmlattr>.critProbability");
weapon->critDamage = root.get<float>("<xmlattr>.critDamage");
@@ -249,13 +317,29 @@ Weapon* parse<items::Weapon> (boost::property_tree::ptree& root)
}
template <>
PlayerController* parse<PlayerController> (boost::property_tree::ptree& root)
components::player::PlayerInventory* parse<components::player::PlayerInventory> (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")
// 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;
PlayerController* controller = new PlayerController();
components::player::PlayerInventory* controller = new components::player::PlayerInventory();
controller->capacity = root.get<uint32_t>("<xmlattr>.capacity");
controller->currentItemIndex = root.get<int>("<xmlattr>.currentItemIndex", -1);
return controller;
}
template <>
components::player::PlayerMovement* parse<components::player::PlayerMovement> (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<int>("<xmlattr>.facingDirection", model::Direction::South);
return controller;
}
@@ -265,7 +349,7 @@ PlayerController* parse<PlayerController> (boost::property_tree::ptree& root)
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)
// 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;
@@ -276,7 +360,7 @@ graphics::BackgroundRenderer* parse<graphics::BackgroundRenderer> (boost::proper
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)
// 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;
@@ -288,57 +372,78 @@ graphics::SpriteRenderer* parse<graphics::SpriteRenderer> (boost::property_tree:
/****** Model ******/
template <>
GameObject* parse<GameObject> (boost::property_tree::ptree& root)
model::GameObject* parse<model::GameObject> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
GameObject* gameObj = new GameObject();
model::GameObject* gameObj = new model::GameObject();
gameObj->name = root.get<std::string>("<xmlattr>.name");
gameObj->visible = root.get<bool>("<xmlattr>.visible", true);
gameObj->setEnabled(root.get<bool>("<xmlattr>.enabled", true));
for (auto child : root)
{
// Game object
if (child.first == "GameObject")
gameObj->addChild(parse<model::GameObject>(child.second));
// Components::basic
if (child.first == "Camera")
gameObj->addComponent(parse<Camera>(child.second));
else if (child.first == "Camera")
gameObj->addComponent(parse<components::basic::Camera>(child.second));
else if (child.first == "Sprite")
gameObj->addComponent(parse<Sprite>(child.second));
gameObj->addComponent(parse<components::basic::Sprite>(child.second));
else if (child.first == "Transform")
gameObj->addComponent(parse<Transform>(child.second));
gameObj->addComponent(parse<components::basic::Transform>(child.second));
// Components::items
else if (child.first == "Axe")
gameObj->addComponent(parse<components::items::Axe>(child.second));
else if (child.first == "Giftable")
gameObj->addComponent(parse<Giftable>(child.second));
gameObj->addComponent(parse<components::items::Giftable>(child.second));
else if (child.first == "Hoe")
gameObj->addComponent(parse<Hoe>(child.second));
gameObj->addComponent(parse<components::items::Hoe>(child.second));
else if (child.first == "Item")
gameObj->addComponent(parse<Item>(child.second));
gameObj->addComponent(parse<components::items::Item>(child.second));
else if (child.first == "Pickaxe")
gameObj->addComponent(parse<components::items::Pickaxe>(child.second));
else if (child.first == "Scythe")
gameObj->addComponent(parse<components::items::Scythe>(child.second));
else if (child.first == "WateringCan")
gameObj->addComponent(parse<components::items::WateringCan>(child.second));
else if (child.first == "Weapon")
gameObj->addComponent(parse<Weapon>(child.second));
gameObj->addComponent(parse<components::items::Weapon>(child.second));
// Components::player
else if (child.first == "PlayerController")
gameObj->addComponent(parse<PlayerController>(child.second));
else if (child.first == "PlayerInventory")
gameObj->addComponent(parse<components::player::PlayerInventory>(child.second));
else if (child.first == "PlayerMovement")
gameObj->addComponent(parse<components::player::PlayerMovement>(child.second));
// Components
else if (child.first == "Background")
gameObj->addComponent(parse<Background>(child.second));
gameObj->addComponent(parse<components::Background>(child.second));
else if (child.first == "DebugController")
gameObj->addComponent(parse<DebugController>(child.second));
gameObj->addComponent(parse<components::DebugController>(child.second));
// Graphics
else if (child.first == "BackgroundRenderer")
gameObj->addComponent(parse<BackgroundRenderer>(child.second));
gameObj->addComponent(parse<graphics::BackgroundRenderer>(child.second));
else if (child.first == "SpriteRenderer")
gameObj->addComponent(parse<SpriteRenderer>(child.second));
gameObj->addComponent(parse<graphics::SpriteRenderer>(child.second));
// !!! Add additional types here !!!
}
@@ -347,52 +452,26 @@ GameObject* parse<GameObject> (boost::property_tree::ptree& root)
}
template <>
Configuration* parse<Configuration> (boost::property_tree::ptree& root)
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)
// 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;
Configuration* config = new Configuration();
model::Configuration* config = new model::Configuration();
config->animationFps = root.get<float>("animationFps");
return config;
}
template <>
Hoe* parse<Hoe> (boost::property_tree::ptree& root)
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 == "Hoe")
root = root.front().second;
Hoe* hoe = new Hoe();
return hoe;
}
template <>
Item* parse<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
Item* item = new 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 <>
Scene* parse<Scene> (boost::property_tree::ptree& root)
{
// Ensure we are on the scene node (property tree seems to add root of its own)
// 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;
Scene* scene = new Scene();
model::Scene* scene = new model::Scene();
scene->cellWidth = root.get<uint32_t>("<xmlattr>.cellWidth");
scene->cellHeight = root.get<uint32_t>("<xmlattr>.cellHeight");
@@ -400,7 +479,7 @@ Scene* parse<Scene> (boost::property_tree::ptree& root)
{
if (child.first == "GameObject")
{
GameObject* obj = parse<GameObject>(child.second);
model::GameObject* obj = parse<model::GameObject>(child.second);
scene->root.addChild(obj);
}
}
@@ -409,13 +488,6 @@ Scene* parse<Scene> (boost::property_tree::ptree& root)
}
/****** Controller namespace ******/
}
}

View File

@@ -13,12 +13,16 @@
#include <components/basic/Sprite.h>
#include <components/basic/Transform.h>
#include <components/DebugController.h>
#include <components/items/Axe.h>
#include <components/items/Giftable.h>
#include <components/items/Hoe.h>
#include <components/items/Item.h>
#include <components/items/Pickaxe.h>
#include <components/items/Scythe.h>
#include <components/items/WateringCan.h>
#include <components/items/Weapon.h>
#include <components/player/PlayerController.h>
#include <components/player/PlayerInventory.h>
#include <components/player/PlayerMovement.h>
#include <graphics/BackgroundRenderer.h>
#include <graphics/SpriteRenderer.h>
@@ -54,6 +58,9 @@ namespace storage {
template <>
components::DebugController* parse<components::DebugController> (boost::property_tree::ptree& root);
template <>
components::items::Axe* parse<components::items::Axe> (boost::property_tree::ptree& root);
template <>
components::items::Giftable* parse<components::items::Giftable> (boost::property_tree::ptree& root);
@@ -63,11 +70,23 @@ namespace storage {
template <>
components::items::Item* parse<components::items::Item> (boost::property_tree::ptree& root);
template <>
components::items::Pickaxe* parse<components::items::Pickaxe> (boost::property_tree::ptree& root);
template <>
components::items::Scythe* parse<components::items::Scythe> (boost::property_tree::ptree& root);
template <>
components::items::WateringCan* parse<components::items::WateringCan> (boost::property_tree::ptree& root);
template <>
components::items::Weapon* parse<components::items::Weapon> (boost::property_tree::ptree& root);
template <>
components::player::PlayerController* parse<components::player::PlayerController> (boost::property_tree::ptree& root);
components::player::PlayerInventory* parse<components::player::PlayerInventory> (boost::property_tree::ptree& root);
template <>
components::player::PlayerMovement* parse<components::player::PlayerMovement> (boost::property_tree::ptree& root);
/****** Graphics ******/
@@ -84,7 +103,6 @@ namespace storage {
template <>
model::GameObject* parse<model::GameObject> (boost::property_tree::ptree& root);
template <>
model::Configuration* parse<model::Configuration> (boost::property_tree::ptree& root);