Player changes:
- reimplemented & improved player inventory - now player has "Action2" which means he can interact with the environment - added weapon energy cost - updated player action interface
This commit is contained in:
parent
6fe33a99a8
commit
6a35b11ec2
@ -11,7 +11,8 @@
|
|||||||
<Weapon damage="0.5"
|
<Weapon damage="0.5"
|
||||||
critProbability="0"
|
critProbability="0"
|
||||||
critDamage="0"
|
critDamage="0"
|
||||||
attackDuration="0.2" />
|
attackDuration="0.2"
|
||||||
|
energyCost="1" />
|
||||||
<Hoe />
|
<Hoe />
|
||||||
</GameObject>
|
</GameObject>
|
||||||
|
|
||||||
@ -25,7 +26,8 @@
|
|||||||
<Weapon damage="0"
|
<Weapon damage="0"
|
||||||
critProbability="0"
|
critProbability="0"
|
||||||
critDamage="0"
|
critDamage="0"
|
||||||
attackDuration="0.2" />
|
attackDuration="0.2"
|
||||||
|
energyCost="1" />
|
||||||
<WateringCan capacity="10" amountLeft="10" />
|
<WateringCan capacity="10" amountLeft="10" />
|
||||||
</GameObject>
|
</GameObject>
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
<Weapon damage="3"
|
<Weapon damage="3"
|
||||||
critProbability="0.01"
|
critProbability="0.01"
|
||||||
critDamage="9"
|
critDamage="9"
|
||||||
attackDuration="0.4" />
|
attackDuration="0.4"
|
||||||
|
energyCost="1.5" />
|
||||||
</GameObject>
|
</GameObject>
|
||||||
|
|
||||||
<GameObject name="Level 2 Sword">
|
<GameObject name="Level 2 Sword">
|
||||||
@ -24,7 +25,8 @@
|
|||||||
<Weapon damage="6"
|
<Weapon damage="6"
|
||||||
critProbability="0.01"
|
critProbability="0.01"
|
||||||
critDamage="18"
|
critDamage="18"
|
||||||
attackDuration="0.4" />
|
attackDuration="0.4"
|
||||||
|
energyCost="0.9" />
|
||||||
</GameObject>
|
</GameObject>
|
||||||
|
|
||||||
</ItemCollection>
|
</ItemCollection>
|
@ -26,12 +26,10 @@
|
|||||||
<Transform x="120" y="100" />
|
<Transform x="120" y="100" />
|
||||||
<Sprite src="sprites/Player.sprite" />
|
<Sprite src="sprites/Player.sprite" />
|
||||||
<SpriteRenderer />
|
<SpriteRenderer />
|
||||||
<PlayerMovement />
|
<Inventory capacity="30" />
|
||||||
<PlayerInventory capacity="30" />
|
<Player hp="100" maxHp="100"
|
||||||
|
energy="100" maxEnergy="100"
|
||||||
<GameObject name="Inventory">
|
money="50" />
|
||||||
<Transform />
|
|
||||||
</GameObject>
|
|
||||||
</GameObject>
|
</GameObject>
|
||||||
|
|
||||||
<!-- Debug object -->
|
<!-- Debug object -->
|
||||||
|
148
src/components/basic/Inventory.cpp
Normal file
148
src/components/basic/Inventory.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Inventory.cpp
|
||||||
|
*
|
||||||
|
* Created on: Dec 11, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <components/basic/Inventory.h>
|
||||||
|
#include <components/basic/InventoryItem.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace components {
|
||||||
|
namespace basic {
|
||||||
|
|
||||||
|
Inventory::Inventory()
|
||||||
|
: m_capacity(10),
|
||||||
|
m_items(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory::~Inventory()
|
||||||
|
{
|
||||||
|
delete[] m_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
model::Component* Inventory::clone()
|
||||||
|
{
|
||||||
|
Inventory* clone = new Inventory();
|
||||||
|
clone->m_capacity = m_capacity;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inventory::dump(unsigned level)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < level; i++)
|
||||||
|
std::cout<<" ";
|
||||||
|
|
||||||
|
std::cout << " .Component: Inventory capacity=" << m_capacity << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inventory::onCreate()
|
||||||
|
{
|
||||||
|
// Allocate items array
|
||||||
|
m_items = new model::GameObject*[m_capacity];
|
||||||
|
memset(m_items, 0, sizeof(m_items[0]) * m_capacity);
|
||||||
|
|
||||||
|
// Find all children
|
||||||
|
for (auto it = gameObject->childrenBegin(); it != gameObject->childrenEnd(); it++)
|
||||||
|
{
|
||||||
|
InventoryItem* item = (*it)->component<InventoryItem>();
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
Assert(item->slot >= 0 && item->slot < m_capacity, "Inventory item slot out of range.");
|
||||||
|
Assert(m_items[item->slot] == nullptr, "Multiple items on one slot.");
|
||||||
|
|
||||||
|
m_items[item->slot] = *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Inventory::add(model::GameObject* item)
|
||||||
|
{
|
||||||
|
Assert(m_items != nullptr, "Inventory not initialized");
|
||||||
|
Assert(item != nullptr, "Cannot add null object.");
|
||||||
|
|
||||||
|
// Find an empty slot
|
||||||
|
size_t slot = (size_t)-1;
|
||||||
|
for (size_t i = 0; i < m_capacity; i++)
|
||||||
|
if (m_items[i] == nullptr)
|
||||||
|
{
|
||||||
|
slot = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot != (size_t)-1)
|
||||||
|
{
|
||||||
|
set(slot, item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inventory::remove(size_t slot)
|
||||||
|
{
|
||||||
|
Assert(m_items != nullptr, "Inventory not initialized.");
|
||||||
|
Assert(slot < m_capacity, "Slot out of range.");
|
||||||
|
|
||||||
|
if (m_items[slot] != nullptr)
|
||||||
|
{
|
||||||
|
m_items[slot]->removeComponent<InventoryItem>();
|
||||||
|
m_items[slot] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inventory::set(size_t slot, model::GameObject* item)
|
||||||
|
{
|
||||||
|
Assert(m_items != nullptr, "Inventory not initialized.");
|
||||||
|
Assert(slot < m_capacity, "Slot out of range.");
|
||||||
|
Assert(item != nullptr, "Cannot set null element.");
|
||||||
|
|
||||||
|
remove(slot);
|
||||||
|
m_items[slot] = item;
|
||||||
|
|
||||||
|
// Update InventoryItem
|
||||||
|
if (!item->haveComponent<InventoryItem>())
|
||||||
|
item->addComponent(new InventoryItem);
|
||||||
|
|
||||||
|
InventoryItem* invItem = item->component<InventoryItem>();
|
||||||
|
invItem->slot = slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
model::GameObject* Inventory::get(size_t slot)
|
||||||
|
{
|
||||||
|
Assert(m_items != nullptr, "Inventory not initialized.");
|
||||||
|
Assert(slot < m_capacity, "Slot out of range.");
|
||||||
|
|
||||||
|
return m_items[slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inventory::setCapacity(size_t capacity)
|
||||||
|
{
|
||||||
|
if (m_items != nullptr)
|
||||||
|
{
|
||||||
|
// Remove extra items
|
||||||
|
for (size_t i = m_capacity; i < capacity; i++)
|
||||||
|
remove(i);
|
||||||
|
|
||||||
|
// Reallocate
|
||||||
|
model::GameObject** old = m_items;
|
||||||
|
m_items = new model::GameObject*[capacity];
|
||||||
|
memset(m_items, 0, sizeof(m_items[0]) * capacity);
|
||||||
|
|
||||||
|
// Copy old objects
|
||||||
|
for (size_t i = 0; i < std::min(m_capacity, capacity); i++)
|
||||||
|
m_items[i] = old[i];
|
||||||
|
|
||||||
|
// Finish
|
||||||
|
delete[] old;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace basic */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
77
src/components/basic/Inventory.h
Normal file
77
src/components/basic/Inventory.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Inventory.h
|
||||||
|
*
|
||||||
|
* Created on: Dec 11, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPONENTS_INVENTORY_INVENTORY_H_
|
||||||
|
#define COMPONENTS_INVENTORY_INVENTORY_H_
|
||||||
|
|
||||||
|
#include <model/Component.h>
|
||||||
|
#include <model/GameObject.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace components {
|
||||||
|
namespace basic {
|
||||||
|
|
||||||
|
class Inventory: public model::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Inventory();
|
||||||
|
virtual ~Inventory();
|
||||||
|
|
||||||
|
virtual model::Component* clone() override;
|
||||||
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
|
virtual void onCreate() override;
|
||||||
|
|
||||||
|
// Inventory management
|
||||||
|
/**
|
||||||
|
* Adds a game object to first available slot.
|
||||||
|
* Game object should be already added as a child of the parent game object.
|
||||||
|
* If object doesn't have an "InventoryItem" component, it will be added.
|
||||||
|
* @returns true if added successfully, false if no empty slot was found.
|
||||||
|
*/
|
||||||
|
bool add(model::GameObject* item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the game object from the given slot.
|
||||||
|
* Doesn't delete/destroy the game object from the parent game object.
|
||||||
|
* Destroys the "InventoryItem" component of the object.
|
||||||
|
*/
|
||||||
|
void remove(size_t slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given game object (which should be a child of the parent game object) to have the given slot.
|
||||||
|
* If there is an item in that slot, it is removed.
|
||||||
|
*/
|
||||||
|
void set(size_t slot, model::GameObject* item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the game object in the given slot.
|
||||||
|
* Returns null if slot is empty.
|
||||||
|
*/
|
||||||
|
model::GameObject* get(size_t slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the capacity of the inventory.
|
||||||
|
* If the inventory is already initialized, objects might be removed.
|
||||||
|
*/
|
||||||
|
void setCapacity(size_t capacity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the capacity
|
||||||
|
*/
|
||||||
|
size_t capacity() const { return m_capacity; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_capacity;
|
||||||
|
model::GameObject** m_items;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace basic */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* COMPONENTS_INVENTORY_INVENTORY_H_ */
|
36
src/components/basic/InventoryItem.cpp
Normal file
36
src/components/basic/InventoryItem.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* InventoryItem.cpp
|
||||||
|
*
|
||||||
|
* Created on: Dec 11, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <components/basic/InventoryItem.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace components {
|
||||||
|
namespace basic {
|
||||||
|
|
||||||
|
InventoryItem::~InventoryItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
model::Component* InventoryItem::clone()
|
||||||
|
{
|
||||||
|
InventoryItem* item = new InventoryItem();
|
||||||
|
item->slot = slot;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InventoryItem::dump(unsigned level)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < level; i++)
|
||||||
|
std::cout<<" ";
|
||||||
|
|
||||||
|
std::cout << " .Component: InventoryItem slot=" << slot << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace basic */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
32
src/components/basic/InventoryItem.h
Normal file
32
src/components/basic/InventoryItem.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* InventoryItem.h
|
||||||
|
*
|
||||||
|
* Created on: Dec 11, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPONENTS_INVENTORY_INVENTORYITEM_H_
|
||||||
|
#define COMPONENTS_INVENTORY_INVENTORYITEM_H_
|
||||||
|
|
||||||
|
#include <model/Component.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace components {
|
||||||
|
namespace basic {
|
||||||
|
|
||||||
|
class InventoryItem: public model::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~InventoryItem();
|
||||||
|
|
||||||
|
virtual model::Component* clone() override;
|
||||||
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
|
size_t slot;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace basic */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* COMPONENTS_INVENTORY_INVENTORYITEM_H_ */
|
@ -34,7 +34,7 @@ void Axe::dump(unsigned level)
|
|||||||
std::cout << " .Component: Axe\n";
|
std::cout << " .Component: Axe\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Axe::performAction(float x, float y, model::Direction d)
|
void Axe::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
#ifndef COMPONENTS_ITEMS_AXE_H_
|
#ifndef COMPONENTS_ITEMS_AXE_H_
|
||||||
#define COMPONENTS_ITEMS_AXE_H_
|
#define COMPONENTS_ITEMS_AXE_H_
|
||||||
|
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Axe: public model::Component, public IPlayerAction
|
class Axe: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Axe();
|
Axe();
|
||||||
@ -24,7 +24,7 @@ namespace items {
|
|||||||
virtual model::Component* clone() override;
|
virtual model::Component* clone() override;
|
||||||
virtual void dump(unsigned level) override;
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace items */
|
} /* namespace items */
|
||||||
|
@ -26,7 +26,7 @@ model::Component* Giftable::clone()
|
|||||||
return new Giftable();
|
return new Giftable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Giftable::performAction(float x, float y, model::Direction d)
|
void Giftable::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
#ifndef CONTROLLER_ITEMS_GIFTABLE_H_
|
#ifndef CONTROLLER_ITEMS_GIFTABLE_H_
|
||||||
#define CONTROLLER_ITEMS_GIFTABLE_H_
|
#define CONTROLLER_ITEMS_GIFTABLE_H_
|
||||||
|
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Giftable: public model::Component, public IPlayerAction
|
class Giftable: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Giftable();
|
Giftable();
|
||||||
@ -24,7 +24,7 @@ namespace items {
|
|||||||
virtual model::Component* clone() override;
|
virtual model::Component* clone() override;
|
||||||
virtual void dump(unsigned level) override;
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace items */
|
} /* namespace items */
|
||||||
|
@ -53,16 +53,13 @@ void Hoe::onInitialize()
|
|||||||
m_map = (*it)->component<Map>();
|
m_map = (*it)->component<Map>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hoe::performAction(float x, float y, model::Direction d)
|
void Hoe::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
Assert(m_map, "No background object!!!");
|
Assert(m_map, "No background object!!!");
|
||||||
|
|
||||||
// Compute watering position
|
// Compute watering position
|
||||||
float digX, digY;
|
size_t col = floorf(lookX);
|
||||||
translate(x, y, d, 0.5f, &digX, &digY);
|
size_t row = floorf(lookY);
|
||||||
|
|
||||||
size_t col = floorf(digX);
|
|
||||||
size_t row = floorf(digY);
|
|
||||||
|
|
||||||
// See what the cell contains
|
// See what the cell contains
|
||||||
Cell backCell = m_map->layer(0).get(row, col);
|
Cell backCell = m_map->layer(0).get(row, col);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#ifndef COMPONENTS_ITEMS_HOE_H_
|
#ifndef COMPONENTS_ITEMS_HOE_H_
|
||||||
#define COMPONENTS_ITEMS_HOE_H_
|
#define COMPONENTS_ITEMS_HOE_H_
|
||||||
|
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <components/Map.h>
|
#include <components/Map.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
#include <model/Direction.h>
|
#include <model/Direction.h>
|
||||||
@ -17,7 +17,7 @@ namespace farmlands {
|
|||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Hoe: public model::Component, public IPlayerAction
|
class Hoe: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Hoe();
|
Hoe();
|
||||||
@ -28,7 +28,7 @@ namespace items {
|
|||||||
|
|
||||||
virtual void onInitialize() override;
|
virtual void onInitialize() override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Map* m_map;
|
Map* m_map;
|
||||||
|
@ -34,7 +34,7 @@ void Pickaxe::dump(unsigned level)
|
|||||||
std::cout << " .Component: Pickaxe\n";
|
std::cout << " .Component: Pickaxe\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pickaxe::performAction(float x, float y, model::Direction d)
|
void Pickaxe::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
#ifndef COMPONENTS_ITEMS_PICKAXE_H_
|
#ifndef COMPONENTS_ITEMS_PICKAXE_H_
|
||||||
#define COMPONENTS_ITEMS_PICKAXE_H_
|
#define COMPONENTS_ITEMS_PICKAXE_H_
|
||||||
|
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Pickaxe: public model::Component, public IPlayerAction
|
class Pickaxe: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Pickaxe();
|
Pickaxe();
|
||||||
@ -24,7 +24,7 @@ namespace items {
|
|||||||
virtual model::Component* clone() override;
|
virtual model::Component* clone() override;
|
||||||
virtual void dump(unsigned level) override;
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace items */
|
} /* namespace items */
|
||||||
|
@ -34,7 +34,7 @@ void Scythe::dump(unsigned level)
|
|||||||
std::cout << " .Component: Scythe\n";
|
std::cout << " .Component: Scythe\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scythe::performAction(float x, float y, model::Direction d)
|
void Scythe::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
#ifndef COMPONENTS_ITEMS_SCYTHE_H_
|
#ifndef COMPONENTS_ITEMS_SCYTHE_H_
|
||||||
#define COMPONENTS_ITEMS_SCYTHE_H_
|
#define COMPONENTS_ITEMS_SCYTHE_H_
|
||||||
|
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Scythe: public model::Component, public IPlayerAction
|
class Scythe: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scythe();
|
Scythe();
|
||||||
@ -24,7 +24,7 @@ namespace items {
|
|||||||
virtual model::Component* clone() override;
|
virtual model::Component* clone() override;
|
||||||
virtual void dump(unsigned level) override;
|
virtual void dump(unsigned level) override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace items */
|
} /* namespace items */
|
||||||
|
@ -23,7 +23,8 @@ namespace items {
|
|||||||
WateringCan::WateringCan()
|
WateringCan::WateringCan()
|
||||||
: capacity(10),
|
: capacity(10),
|
||||||
amountLeft(10),
|
amountLeft(10),
|
||||||
m_map(nullptr)
|
m_map(nullptr),
|
||||||
|
m_grid(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,16 +63,13 @@ void WateringCan::onInitialize()
|
|||||||
m_grid = (*gridIt)->component<basic::Grid>();
|
m_grid = (*gridIt)->component<basic::Grid>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WateringCan::performAction(float x, float y, model::Direction d)
|
void WateringCan::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
Assert(m_map, "No background object!!!");
|
Assert(m_map, "No background object!!!");
|
||||||
|
|
||||||
// Compute watering position
|
// Compute watering position
|
||||||
float digX, digY;
|
size_t col = floorf(lookX);
|
||||||
translate(x, y, d, 0.5f, &digX, &digY);
|
size_t row = floorf(lookY);
|
||||||
|
|
||||||
size_t col = floorf(digX);
|
|
||||||
size_t row = floorf(digY);
|
|
||||||
|
|
||||||
// See what the cell contains
|
// See what the cell contains
|
||||||
Cell backCell = m_map->layer(0).get(row, col);
|
Cell backCell = m_map->layer(0).get(row, col);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define COMPONENTS_ITEMS_WATERINGCAN_H_
|
#define COMPONENTS_ITEMS_WATERINGCAN_H_
|
||||||
|
|
||||||
#include <components/basic/Grid.h>
|
#include <components/basic/Grid.h>
|
||||||
#include <components/items/IPlayerAction.h>
|
#include <model/IPlayerAction.h>
|
||||||
#include <components/Map.h>
|
#include <components/Map.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
#include <model/Direction.h>
|
#include <model/Direction.h>
|
||||||
@ -18,7 +18,7 @@ namespace farmlands {
|
|||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class WateringCan: public model::Component, public IPlayerAction
|
class WateringCan: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WateringCan();
|
WateringCan();
|
||||||
@ -29,7 +29,7 @@ namespace items {
|
|||||||
|
|
||||||
virtual void onInitialize() override;
|
virtual void onInitialize() override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
|
|
||||||
void fillCan();
|
void fillCan();
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ Weapon::Weapon()
|
|||||||
critDamage(0),
|
critDamage(0),
|
||||||
attackDuration(1.0f),
|
attackDuration(1.0f),
|
||||||
attackTimeLeft(0),
|
attackTimeLeft(0),
|
||||||
|
energyCost(0),
|
||||||
m_sprite(nullptr)
|
m_sprite(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -57,12 +58,10 @@ void Weapon::onUpdateLogic()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weapon::performAction(float x, float y, model::Direction d)
|
void Weapon::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energCost)
|
||||||
{
|
{
|
||||||
if (attackTimeLeft <= 0)
|
*timeCost = attackTimeLeft = attackDuration;
|
||||||
{
|
*energCost = energyCost;
|
||||||
attackTimeLeft = attackDuration;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weapon::dump(unsigned level)
|
void Weapon::dump(unsigned level)
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
#define CONTROLLER_ITEMS_WEAPON_H_
|
#define CONTROLLER_ITEMS_WEAPON_H_
|
||||||
|
|
||||||
#include <components/basic/Sprite.h>
|
#include <components/basic/Sprite.h>
|
||||||
#include <components/items/IPlayerAction.h>
|
|
||||||
#include <graphics/SpriteRenderer.h>
|
#include <graphics/SpriteRenderer.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
#include <model/IPlayerAction.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace items {
|
namespace items {
|
||||||
|
|
||||||
class Weapon: public model::Component, public IPlayerAction
|
class Weapon: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Weapon();
|
Weapon();
|
||||||
@ -33,7 +33,7 @@ namespace items {
|
|||||||
/**
|
/**
|
||||||
* Performs everything required to attacking an enemy with a weapon. To be called from player controller.
|
* Performs everything required to attacking an enemy with a weapon. To be called from player controller.
|
||||||
*/
|
*/
|
||||||
virtual void performAction(float x, float y, model::Direction d);
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
float damage;
|
float damage;
|
||||||
@ -43,6 +43,8 @@ namespace items {
|
|||||||
float attackDuration; // In seconds
|
float attackDuration; // In seconds
|
||||||
float attackTimeLeft;
|
float attackTimeLeft;
|
||||||
|
|
||||||
|
float energyCost;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
basic::Sprite* m_sprite;
|
basic::Sprite* m_sprite;
|
||||||
};
|
};
|
||||||
|
@ -70,14 +70,11 @@ void Seed::onInitialize()
|
|||||||
m_map = (*mapIt)->component<Map>();
|
m_map = (*mapIt)->component<Map>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Seed::performAction(float x, float y, model::Direction d)
|
void Seed::performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost)
|
||||||
{
|
{
|
||||||
// Compute planting position
|
// Compute planting position
|
||||||
float digX, digY;
|
size_t col = floorf(lookX);
|
||||||
translate(x, y, d, 0.5f, &digX, &digY);
|
size_t row = floorf(lookY);
|
||||||
|
|
||||||
size_t col = floorf(digX);
|
|
||||||
size_t row = floorf(digY);
|
|
||||||
|
|
||||||
// Soil is located on layer 1
|
// Soil is located on layer 1
|
||||||
Cell cell = m_map->layer(1).get(row, col);
|
Cell cell = m_map->layer(1).get(row, col);
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
#define COMPONENTS_ITEMS_SEED_H_
|
#define COMPONENTS_ITEMS_SEED_H_
|
||||||
|
|
||||||
#include <components/basic/Grid.h>
|
#include <components/basic/Grid.h>
|
||||||
#include <components/items/IPlayerAction.h>
|
|
||||||
#include <components/Map.h>
|
#include <components/Map.h>
|
||||||
|
#include <model/IPlayerAction.h>
|
||||||
#include <model/Component.h>
|
#include <model/Component.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace components {
|
||||||
namespace plants {
|
namespace plants {
|
||||||
|
|
||||||
class Seed: public model::Component, public items::IPlayerAction
|
class Seed: public model::Component, public model::IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Seed();
|
Seed();
|
||||||
@ -28,7 +28,7 @@ namespace plants {
|
|||||||
|
|
||||||
virtual void onInitialize() override;
|
virtual void onInitialize() override;
|
||||||
|
|
||||||
virtual void performAction(float x, float y, model::Direction d) override;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) override;
|
||||||
|
|
||||||
std::string plantName;
|
std::string plantName;
|
||||||
|
|
||||||
|
349
src/components/player/Player.cpp
Normal file
349
src/components/player/Player.cpp
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
/*
|
||||||
|
* Player.cpp
|
||||||
|
*
|
||||||
|
* Created on: Dec 10, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <GameState.h>
|
||||||
|
#include <components/player/Player.h>
|
||||||
|
#include <input/Input.h>
|
||||||
|
#include <math/GameMath.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.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distance from player position to "look" position.
|
||||||
|
* This position is used for picking the cell which will be affected by the player's actions.
|
||||||
|
*/
|
||||||
|
static const float PlayerLookDistance = 0.5f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map between velocity and direction.
|
||||||
|
*/
|
||||||
|
static const Direction VelocitySignDirections[3][3] =
|
||||||
|
{
|
||||||
|
{ Direction::NorthWest, Direction::West, Direction::SouthWest },
|
||||||
|
{ Direction::North, Direction::None, Direction::South },
|
||||||
|
{ Direction::NorthEast, Direction::East, Direction::SouthEast },
|
||||||
|
};
|
||||||
|
|
||||||
|
Player::Player()
|
||||||
|
: selectedItemIndex(-1),
|
||||||
|
selectedItem(nullptr),
|
||||||
|
selectedWeapon(nullptr),
|
||||||
|
itemActionTimeLeft(0),
|
||||||
|
facingDirection(Direction::South),
|
||||||
|
walking(false),
|
||||||
|
running(false),
|
||||||
|
lookX(0), lookY(0),
|
||||||
|
hp(100), maxHp(100),
|
||||||
|
energy(100), maxEnergy(100),
|
||||||
|
money(0),
|
||||||
|
m_transform(nullptr),
|
||||||
|
m_inventory(nullptr),
|
||||||
|
m_grid(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Player::~Player()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Component* Player::clone()
|
||||||
|
{
|
||||||
|
Player* clone = new Player();
|
||||||
|
|
||||||
|
// Inventory
|
||||||
|
clone->selectedItemIndex = selectedItemIndex;
|
||||||
|
clone->itemActionTimeLeft = itemActionTimeLeft;
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
clone->facingDirection = facingDirection;
|
||||||
|
clone->walking = walking;
|
||||||
|
clone->running = running;
|
||||||
|
|
||||||
|
// The position at which the player is looking
|
||||||
|
clone->lookX = lookX;
|
||||||
|
clone->lookY = lookY;
|
||||||
|
|
||||||
|
// Health
|
||||||
|
clone->hp = hp;
|
||||||
|
clone->energy = energy;
|
||||||
|
|
||||||
|
// Cash
|
||||||
|
clone->money = money;
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::dump(unsigned level)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < level; i++)
|
||||||
|
std::cout<<" ";
|
||||||
|
|
||||||
|
std::cout << " .Component: Player\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::onInitialize()
|
||||||
|
{
|
||||||
|
m_transform = gameObject->component<Transform>();
|
||||||
|
m_inventory = gameObject->component<Inventory>();
|
||||||
|
|
||||||
|
// Search for the object which has the grid
|
||||||
|
auto root = &GameState::current().scene->root;
|
||||||
|
auto gridIt = root->findByComponent<Grid>();
|
||||||
|
Assert(gridIt != root->childrenEnd(), "Cannot find grid component.");
|
||||||
|
m_grid = (*gridIt)->component<Grid>();
|
||||||
|
|
||||||
|
initializeInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Player::onEvent(SDL_Event& event)
|
||||||
|
{
|
||||||
|
handleInventoryDropEvent(event);
|
||||||
|
handleInventorySetEvent(event);
|
||||||
|
handleActionEvents(event);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::onUpdateLogic()
|
||||||
|
{
|
||||||
|
itemActionTimeLeft -= GameState::current().deltaTime;
|
||||||
|
hp = clamp(hp, 0, maxHp);
|
||||||
|
energy = clamp(energy, 0, maxEnergy);
|
||||||
|
|
||||||
|
updateMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::onPreRender()
|
||||||
|
{
|
||||||
|
preRenderSelectedItem();
|
||||||
|
preRenderMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::initializeInventory()
|
||||||
|
{
|
||||||
|
Assert(m_inventory != nullptr, "Inventory component is missing!");
|
||||||
|
|
||||||
|
// Get currently selected item
|
||||||
|
if (selectedItem >= 0 && selectedItemIndex < m_inventory->capacity())
|
||||||
|
{
|
||||||
|
selectedItem = m_inventory->get(static_cast<size_t>(selectedItemIndex));
|
||||||
|
selectedWeapon = (selectedItem != nullptr) ? selectedItem->component<items::Weapon>() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set enabled state of inventory items
|
||||||
|
for (size_t i = 0; i < m_inventory->capacity(); i++)
|
||||||
|
{
|
||||||
|
GameObject* obj = m_inventory->get(i);
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
obj->setEnabled(i == static_cast<size_t>(selectedItemIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handleInventoryDropEvent(SDL_Event& event)
|
||||||
|
{
|
||||||
|
bool inventoryDrop = Input::instance().down(GameKey::InventoryDrop, event);
|
||||||
|
|
||||||
|
if (inventoryDrop && selectedItemIndex >= 0)
|
||||||
|
{
|
||||||
|
// TODO: convert to 'pickable' item instead of destroying
|
||||||
|
m_inventory->remove(static_cast<size_t>(selectedItemIndex));
|
||||||
|
gameObject->destroyChild(selectedItem);
|
||||||
|
|
||||||
|
selectedItemIndex = -1;
|
||||||
|
selectedItem = nullptr;
|
||||||
|
selectedWeapon = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handleInventorySetEvent(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 < m_inventory->capacity())
|
||||||
|
{
|
||||||
|
// Disable old object
|
||||||
|
if (selectedItem != nullptr)
|
||||||
|
selectedItem->setEnabled(false);
|
||||||
|
|
||||||
|
// Obtain new object
|
||||||
|
selectedItemIndex = slot;
|
||||||
|
selectedItem = m_inventory->get(slot);
|
||||||
|
selectedWeapon = (selectedItem != nullptr) ? selectedItem->component<items::Weapon>() : nullptr;
|
||||||
|
|
||||||
|
// Enable new object
|
||||||
|
if (selectedItem)
|
||||||
|
selectedItem->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::preRenderSelectedItem()
|
||||||
|
{
|
||||||
|
// Set item position
|
||||||
|
if (selectedItem)
|
||||||
|
{
|
||||||
|
basic::Transform* itemTransf = selectedItem->component<basic::Transform>();
|
||||||
|
|
||||||
|
if (facingDirection & Direction::East)
|
||||||
|
{
|
||||||
|
itemTransf->x = 0.2f;
|
||||||
|
itemTransf->y = -0.8f;
|
||||||
|
}
|
||||||
|
else if (facingDirection & Direction::West)
|
||||||
|
{
|
||||||
|
itemTransf->x = -0.8f;
|
||||||
|
itemTransf->y = -0.8f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::preRenderMovement()
|
||||||
|
{
|
||||||
|
// 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 (itemActionTimeLeft > 0)
|
||||||
|
animVelocity = 0.1f;
|
||||||
|
// TODO: move this animation velocity change somewhere else
|
||||||
|
|
||||||
|
sprite->animationVelocity = animVelocity;
|
||||||
|
|
||||||
|
// Set camera
|
||||||
|
Transform* cam = GameState::current().renderContext.cameraTransform();
|
||||||
|
cam->x = m_transform->x;
|
||||||
|
cam->y = m_transform->y - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::updateMovement()
|
||||||
|
{
|
||||||
|
running = Input::instance().pressed(GameKey::Run);
|
||||||
|
walking = false;
|
||||||
|
|
||||||
|
// Compute movement velocity
|
||||||
|
float velMultiplier = PlayerWalkVelocity;
|
||||||
|
|
||||||
|
if (itemActionTimeLeft > 0)
|
||||||
|
velMultiplier = PlayerAttackVelocity;
|
||||||
|
else if (running)
|
||||||
|
velMultiplier = PlayerRunVelocity;
|
||||||
|
|
||||||
|
velMultiplier *= GameState::current().deltaTime;
|
||||||
|
|
||||||
|
// Compute movement positions
|
||||||
|
float vx = Input::instance().getX() * velMultiplier;
|
||||||
|
float vy = Input::instance().getY() * velMultiplier;
|
||||||
|
float newX = m_transform->x + vx;
|
||||||
|
float newY = m_transform->y + vy;
|
||||||
|
|
||||||
|
if ((vx || vy) && canMove(newX, newY))
|
||||||
|
{
|
||||||
|
m_transform->x = newX;
|
||||||
|
m_transform->y = newY;
|
||||||
|
|
||||||
|
walking = true;
|
||||||
|
facingDirection = getDirection(vx, vy);
|
||||||
|
|
||||||
|
translate(newX, newY, facingDirection, PlayerLookDistance, &lookX, &lookY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction Player::getDirection(float vx, float vy)
|
||||||
|
{
|
||||||
|
int xx = (0 < vx) - (vx < 0);
|
||||||
|
int yy = (0 < vy) - (vy < 0);
|
||||||
|
|
||||||
|
return VelocitySignDirections[xx + 1][yy + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::handleActionEvents(SDL_Event& event)
|
||||||
|
{
|
||||||
|
bool action1 = Input::instance().down(GameKey::Action, event);
|
||||||
|
bool action2 = Input::instance().down(GameKey::Action2, event);
|
||||||
|
|
||||||
|
if (action1 && itemActionTimeLeft <= 0)
|
||||||
|
{
|
||||||
|
performAction(selectedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action2 && itemActionTimeLeft <= 0)
|
||||||
|
{
|
||||||
|
GameObject* obj = m_grid->get(lookX, lookY);
|
||||||
|
performAction(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::performAction(model::GameObject* obj)
|
||||||
|
{
|
||||||
|
if (obj == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call components which implement ITool
|
||||||
|
for (auto it = obj->componentsBegin(); it != obj->componentsEnd(); it++)
|
||||||
|
{
|
||||||
|
IPlayerAction* action = dynamic_cast<IPlayerAction*>(it->second);
|
||||||
|
if (action != nullptr)
|
||||||
|
{
|
||||||
|
float timeCost = 0;
|
||||||
|
float hpCost = 0;
|
||||||
|
float energyCost = 0;
|
||||||
|
|
||||||
|
action->performAction(lookX, lookY, &timeCost, &hpCost, &energyCost);
|
||||||
|
|
||||||
|
itemActionTimeLeft += timeCost;
|
||||||
|
hp -= hpCost;
|
||||||
|
energy -= energyCost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace player */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
87
src/components/player/Player.h
Normal file
87
src/components/player/Player.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Player.h
|
||||||
|
*
|
||||||
|
* Created on: Dec 10, 2016
|
||||||
|
* Author: tibi
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPONENTS_PLAYER_PLAYER_H_
|
||||||
|
#define COMPONENTS_PLAYER_PLAYER_H_
|
||||||
|
|
||||||
|
#include <components/basic/Grid.h>
|
||||||
|
#include <components/basic/Inventory.h>
|
||||||
|
#include <components/basic/Transform.h>
|
||||||
|
#include <components/items/Weapon.h>
|
||||||
|
#include <model/Component.h>
|
||||||
|
#include <model/Direction.h>
|
||||||
|
#include <model/GameObject.h>
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
namespace farmlands {
|
||||||
|
namespace components {
|
||||||
|
namespace player {
|
||||||
|
|
||||||
|
class Player: public model::Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Player();
|
||||||
|
virtual ~Player();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Inventory
|
||||||
|
int selectedItemIndex;
|
||||||
|
model::GameObject* selectedItem;
|
||||||
|
items::Weapon* selectedWeapon;
|
||||||
|
|
||||||
|
float itemActionTimeLeft;
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
model::Direction facingDirection;
|
||||||
|
bool walking, running;
|
||||||
|
|
||||||
|
// The position at which the player is looking
|
||||||
|
float lookX, lookY;
|
||||||
|
|
||||||
|
// Health, energy
|
||||||
|
float hp, maxHp;
|
||||||
|
float energy, maxEnergy;
|
||||||
|
|
||||||
|
// Cash
|
||||||
|
uint32_t money;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Inventory
|
||||||
|
void initializeInventory();
|
||||||
|
void handleInventoryDropEvent(SDL_Event& event);
|
||||||
|
void handleInventorySetEvent(SDL_Event& event);
|
||||||
|
void preRenderSelectedItem();
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
void preRenderMovement();
|
||||||
|
void updateMovement();
|
||||||
|
bool canMove(float x, float y) { return true; }
|
||||||
|
static model::Direction getDirection(float vx, float vy);
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
void handleActionEvents(SDL_Event& event);
|
||||||
|
void performAction(model::GameObject* obj);
|
||||||
|
|
||||||
|
basic::Transform* m_transform;
|
||||||
|
basic::Inventory* m_inventory;
|
||||||
|
basic::Grid* m_grid;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace player */
|
||||||
|
} /* namespace components */
|
||||||
|
} /* namespace farmlands */
|
||||||
|
|
||||||
|
#endif /* COMPONENTS_PLAYER_PLAYER_H_ */
|
@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
handleCurrentInventoryItemEvent(event);
|
|
||||||
handleInventoryEvents(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerInventory::onUpdateLogic()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerInventory::onPreRender()
|
|
||||||
{
|
|
||||||
// Set item position
|
|
||||||
if (currentItem)
|
|
||||||
{
|
|
||||||
Transform* itemTransf = currentItem->component<Transform>();
|
|
||||||
|
|
||||||
if (m_playerMovement->facingDirection & Direction::East)
|
|
||||||
{
|
|
||||||
itemTransf->x = 0.2f;
|
|
||||||
itemTransf->y = -0.8f;
|
|
||||||
}
|
|
||||||
else if (m_playerMovement->facingDirection & Direction::West)
|
|
||||||
{
|
|
||||||
itemTransf->x = -0.8f;
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
IPlayerAction* tool = dynamic_cast<IPlayerAction*>(it->second);
|
|
||||||
if (tool != nullptr)
|
|
||||||
tool->performAction(x, y, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerInventory::handleCurrentInventoryItemEvent(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);
|
|
||||||
}
|
|
||||||
else if (0 <= slot)
|
|
||||||
{
|
|
||||||
std::cout << "Slot " << slot << "empty\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerInventory::handleInventoryEvents(SDL_Event& event)
|
|
||||||
{
|
|
||||||
bool inventoryDrop = Input::instance().down(GameKey::InventoryDrop, event);
|
|
||||||
|
|
||||||
if (inventoryDrop && currentItem != nullptr)
|
|
||||||
{
|
|
||||||
// For now we delete the object. We may want to save its state later on
|
|
||||||
m_inventory->destroyChild(currentItem);
|
|
||||||
|
|
||||||
currentItemIndex = -1;
|
|
||||||
currentItem = nullptr;
|
|
||||||
currentWeapon = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* namespace player */
|
|
||||||
} /* namespace components */
|
|
||||||
} /* namespace farmlands */
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 handleCurrentInventoryItemEvent(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_ */
|
|
@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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().deltaTime;
|
|
||||||
|
|
||||||
// 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 */
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* PlayerController.h
|
|
||||||
*
|
|
||||||
* Created on: Nov 27, 2016
|
|
||||||
* Author: tibi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONTROLLER_PLAYERCONTROLLER_H_
|
|
||||||
#define CONTROLLER_PLAYERCONTROLLER_H_
|
|
||||||
|
|
||||||
#include <components/basic/Transform.h>
|
|
||||||
#include <components/items/Weapon.h>
|
|
||||||
#include <model/Component.h>
|
|
||||||
#include <model/Direction.h>
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
#define MAX_INVENTORY_SIZE 50
|
|
||||||
|
|
||||||
namespace farmlands {
|
|
||||||
namespace components {
|
|
||||||
namespace player {
|
|
||||||
|
|
||||||
class PlayerInventory;
|
|
||||||
|
|
||||||
class PlayerMovement : public model::Component
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PlayerMovement();
|
|
||||||
virtual ~PlayerMovement();
|
|
||||||
|
|
||||||
virtual model::Component* clone() override;
|
|
||||||
virtual void dump(unsigned level) override;
|
|
||||||
|
|
||||||
virtual void onInitialize() override;
|
|
||||||
virtual void onUpdateLogic() override;
|
|
||||||
virtual void onPreRender() override;
|
|
||||||
|
|
||||||
model::Direction facingDirection;
|
|
||||||
bool walking, running;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static model::Direction getDirection(float vx, float vy);
|
|
||||||
bool canMove(float x, float y);
|
|
||||||
|
|
||||||
// Movement
|
|
||||||
basic::Transform* m_transform;
|
|
||||||
|
|
||||||
// For getting speed
|
|
||||||
PlayerInventory* m_inventory;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
} /* namespace components */
|
|
||||||
} /* namespace farmlands */
|
|
||||||
|
|
||||||
#endif /* CONTROLLER_PLAYERCONTROLLER_H_ */
|
|
@ -158,7 +158,7 @@ namespace model {
|
|||||||
auto it = m_components.find(typeIndex);
|
auto it = m_components.find(typeIndex);
|
||||||
if (it != m_components.end())
|
if (it != m_components.end())
|
||||||
{
|
{
|
||||||
comp = it->second;
|
comp = dynamic_cast<T*>(it->second);
|
||||||
m_components.erase(it);
|
m_components.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,20 +11,16 @@
|
|||||||
#include <model/Direction.h>
|
#include <model/Direction.h>
|
||||||
|
|
||||||
namespace farmlands {
|
namespace farmlands {
|
||||||
namespace components {
|
namespace model {
|
||||||
namespace items {
|
|
||||||
|
|
||||||
class IPlayerAction
|
class IPlayerAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IPlayerAction() { }
|
virtual ~IPlayerAction() { }
|
||||||
virtual void performAction(float playerX, float playerY, model::Direction) = 0;
|
virtual void performAction(float lookX, float lookY, float* timeCost, float* hpCost, float* energyCost) = 0;
|
||||||
|
|
||||||
float actionCost;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace items */
|
} /* namespace model */
|
||||||
} /* namespace components */
|
|
||||||
} /* namespace farmlands */
|
} /* namespace farmlands */
|
||||||
|
|
||||||
#endif /* COMPONENTS_ITEMS_IPLAYERACTION_H_ */
|
#endif /* COMPONENTS_ITEMS_IPLAYERACTION_H_ */
|
@ -93,14 +93,20 @@ void ResourceManager::loadGame()
|
|||||||
// Get to "Inventory" object
|
// Get to "Inventory" object
|
||||||
model::GameObject* root = &GameState::current().scene->root;
|
model::GameObject* root = &GameState::current().scene->root;
|
||||||
model::GameObject* player = *root->findByName("Player");
|
model::GameObject* player = *root->findByName("Player");
|
||||||
model::GameObject* inventory = *player->findByName("Inventory");
|
components::basic::Inventory* inventory = player->component<components::basic::Inventory>();
|
||||||
|
|
||||||
// Give player all items
|
// Give player all items
|
||||||
for (auto prefab : GameState::current().itemPrefabs)
|
for (auto prefab : GameState::current().itemPrefabs)
|
||||||
model::GameObject::instantiate(prefab, "inv item", inventory);
|
{
|
||||||
|
model::GameObject* item = model::GameObject::instantiate(prefab, "inv item", player);
|
||||||
|
inventory->add(item);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto prefab : GameState::current().seedsPrefabs)
|
for (auto prefab : GameState::current().seedsPrefabs)
|
||||||
model::GameObject::instantiate(prefab, "inv seed", inventory);
|
{
|
||||||
|
model::GameObject* item = model::GameObject::instantiate(prefab, "inv seed", player);
|
||||||
|
inventory->add(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::getPath(ResourceId resourceId)
|
std::string ResourceManager::getPath(ResourceId resourceId)
|
||||||
|
@ -97,7 +97,6 @@ components::Map* parse<components::Map> (boost::property_tree::ptree& root)
|
|||||||
parseMapCells(cellsId, map, layer);
|
parseMapCells(cellsId, map, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
@ -158,6 +157,34 @@ components::basic::Grid* parse<components::basic::Grid> (boost::property_tree::p
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
components::basic::Inventory* parse<components::basic::Inventory> (boost::property_tree::ptree& root)
|
||||||
|
{
|
||||||
|
// Ensure we are on the correct node (property tree seems to add root of its own)
|
||||||
|
if (root.size() > 0 && root.front().first == "Inventory")
|
||||||
|
root = root.front().second;
|
||||||
|
|
||||||
|
components::basic::Inventory* inventory = new components::basic::Inventory();
|
||||||
|
|
||||||
|
size_t capacity = root.get<size_t>("<xmlattr>.capacity");
|
||||||
|
inventory->setCapacity(capacity);
|
||||||
|
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
components::basic::InventoryItem* parse<components::basic::InventoryItem> (boost::property_tree::ptree& root)
|
||||||
|
{
|
||||||
|
// Ensure we are on the correct node (property tree seems to add root of its own)
|
||||||
|
if (root.size() > 0 && root.front().first == "InventoryItem")
|
||||||
|
root = root.front().second;
|
||||||
|
|
||||||
|
components::basic::InventoryItem* item = new components::basic::InventoryItem();
|
||||||
|
item->slot = root.get<size_t>("<xmlattr>.slot");
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
components::basic::Sprite* parse<components::basic::Sprite> (boost::property_tree::ptree& root)
|
components::basic::Sprite* parse<components::basic::Sprite> (boost::property_tree::ptree& root)
|
||||||
{
|
{
|
||||||
@ -382,6 +409,7 @@ components::items::Weapon* parse<components::items::Weapon> (boost::property_tre
|
|||||||
weapon->critProbability = root.get<float>("<xmlattr>.critProbability");
|
weapon->critProbability = root.get<float>("<xmlattr>.critProbability");
|
||||||
weapon->critDamage = root.get<float>("<xmlattr>.critDamage");
|
weapon->critDamage = root.get<float>("<xmlattr>.critDamage");
|
||||||
weapon->attackDuration = root.get<float>("<xmlattr>.attackDuration");
|
weapon->attackDuration = root.get<float>("<xmlattr>.attackDuration");
|
||||||
|
weapon->energyCost = root.get<float>("<xmlattr>.energyCost");
|
||||||
return weapon;
|
return weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,34 +451,58 @@ components::plants::Seed* parse<components::plants::Seed> (boost::property_tree:
|
|||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
model::Direction parseDirection(std::string directionStr)
|
||||||
components::player::PlayerInventory* parse<components::player::PlayerInventory> (boost::property_tree::ptree& root)
|
|
||||||
{
|
{
|
||||||
// Ensure we are on the correct node (property tree seems to add root of its own)
|
model::Direction direction = model::Direction::None;
|
||||||
if (root.size() > 0 && root.front().first == "PlayerInventory")
|
boost::to_lower(directionStr);
|
||||||
root = root.front().second;
|
|
||||||
|
|
||||||
components::player::PlayerInventory* controller = new components::player::PlayerInventory();
|
if (boost::contains(directionStr, "east"))
|
||||||
controller->capacity = root.get<uint32_t>("<xmlattr>.capacity");
|
direction = (model::Direction) (direction | model::Direction::East);
|
||||||
controller->currentItemIndex = root.get<int>("<xmlattr>.currentItemIndex", -1);
|
if (boost::contains(directionStr, "north"))
|
||||||
|
direction = (model::Direction) (direction | model::Direction::North);
|
||||||
|
if (boost::contains(directionStr, "west"))
|
||||||
|
direction = (model::Direction) (direction | model::Direction::West);
|
||||||
|
if (boost::contains(directionStr, "south"))
|
||||||
|
direction = (model::Direction) (direction | model::Direction::South);
|
||||||
|
|
||||||
return controller;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
components::player::PlayerMovement* parse<components::player::PlayerMovement> (boost::property_tree::ptree& root)
|
components::player::Player* parse<components::player::Player> (boost::property_tree::ptree& root)
|
||||||
{
|
{
|
||||||
// Ensure we are on the correct node (property tree seems to add root of its own)
|
// Ensure we are on the correct node (property tree seems to add root of its own)
|
||||||
if (root.size() > 0 && root.front().first == "PlayerMovement")
|
if (root.size() > 0 && root.front().first == "Player")
|
||||||
root = root.front().second;
|
root = root.front().second;
|
||||||
|
|
||||||
components::player::PlayerMovement* controller = new components::player::PlayerMovement();
|
components::player::Player* player = new components::player::Player();
|
||||||
controller->facingDirection = (model::Direction)root.get<int>("<xmlattr>.facingDirection", model::Direction::South);
|
|
||||||
|
|
||||||
return controller;
|
// Inventory
|
||||||
|
player->selectedItemIndex = root.get<int>("<xmlattr>.selectedItemIndex", -1);
|
||||||
|
player->itemActionTimeLeft = root.get<float>("<xmlattr>.itemActionTimeLeft", 0.0f);
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
std::string direction = root.get<std::string>("<xmlattr>.facingDirection", "South");
|
||||||
|
player->facingDirection = parseDirection(direction);
|
||||||
|
player->walking = root.get<bool>("<xmlattr>.walking", false);
|
||||||
|
player->running = root.get<bool>("<xmlattr>.running", false);
|
||||||
|
|
||||||
|
// Looking
|
||||||
|
player->lookX = root.get<float>("<xmlattr>.lookX", 0.0f);
|
||||||
|
player->lookY = root.get<float>("<xmlattr>.lookY", 0.0f);
|
||||||
|
|
||||||
|
// Health, energy
|
||||||
|
player->hp = root.get<float>("<xmlattr>.hp", 100.0f);
|
||||||
|
player->maxHp = root.get<float>("<xmlattr>.maxHp", 100.0f);
|
||||||
|
player->energy = root.get<float>("<xmlattr>.energy", 100.0f);
|
||||||
|
player->maxEnergy = root.get<float>("<xmlattr>.maxEnergy", 100.0f);
|
||||||
|
|
||||||
|
// Cash
|
||||||
|
player->money = root.get<uint32_t>("<xmlattr>.money", 0u);
|
||||||
|
|
||||||
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****** Graphics ******/
|
/****** Graphics ******/
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@ -503,6 +555,12 @@ model::GameObject* parse<model::GameObject> (boost::property_tree::ptree& root)
|
|||||||
else if (child.first == "Grid")
|
else if (child.first == "Grid")
|
||||||
gameObj->addComponent(parse<components::basic::Grid>(child.second));
|
gameObj->addComponent(parse<components::basic::Grid>(child.second));
|
||||||
|
|
||||||
|
else if (child.first == "Inventory")
|
||||||
|
gameObj->addComponent(parse<components::basic::Inventory>(child.second));
|
||||||
|
|
||||||
|
else if (child.first == "InventoryItem")
|
||||||
|
gameObj->addComponent(parse<components::basic::InventoryItem>(child.second));
|
||||||
|
|
||||||
else if (child.first == "Sprite")
|
else if (child.first == "Sprite")
|
||||||
gameObj->addComponent(parse<components::basic::Sprite>(child.second));
|
gameObj->addComponent(parse<components::basic::Sprite>(child.second));
|
||||||
|
|
||||||
@ -542,11 +600,8 @@ model::GameObject* parse<model::GameObject> (boost::property_tree::ptree& root)
|
|||||||
gameObj->addComponent(parse<components::plants::Seed>(child.second));
|
gameObj->addComponent(parse<components::plants::Seed>(child.second));
|
||||||
|
|
||||||
// Components::player
|
// Components::player
|
||||||
else if (child.first == "PlayerInventory")
|
else if (child.first == "Player")
|
||||||
gameObj->addComponent(parse<components::player::PlayerInventory>(child.second));
|
gameObj->addComponent(parse<components::player::Player>(child.second));
|
||||||
|
|
||||||
else if (child.first == "PlayerMovement")
|
|
||||||
gameObj->addComponent(parse<components::player::PlayerMovement>(child.second));
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
else if (child.first == "DebugController")
|
else if (child.first == "DebugController")
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <components/basic/Camera.h>
|
#include <components/basic/Camera.h>
|
||||||
#include <components/basic/Grid.h>
|
#include <components/basic/Grid.h>
|
||||||
|
#include <components/basic/Inventory.h>
|
||||||
|
#include <components/basic/InventoryItem.h>
|
||||||
#include <components/basic/Sprite.h>
|
#include <components/basic/Sprite.h>
|
||||||
#include <components/basic/Transform.h>
|
#include <components/basic/Transform.h>
|
||||||
#include <components/DebugController.h>
|
#include <components/DebugController.h>
|
||||||
@ -26,8 +28,7 @@
|
|||||||
#include <components/Map.h>
|
#include <components/Map.h>
|
||||||
#include <components/plants/Plant.h>
|
#include <components/plants/Plant.h>
|
||||||
#include <components/plants/Seed.h>
|
#include <components/plants/Seed.h>
|
||||||
#include <components/player/PlayerInventory.h>
|
#include <components/player/Player.h>
|
||||||
#include <components/player/PlayerMovement.h>
|
|
||||||
#include <graphics/MapRenderer.h>
|
#include <graphics/MapRenderer.h>
|
||||||
#include <graphics/SpriteRenderer.h>
|
#include <graphics/SpriteRenderer.h>
|
||||||
#include <model/GameObject.h>
|
#include <model/GameObject.h>
|
||||||
@ -54,6 +55,12 @@ namespace storage {
|
|||||||
template <>
|
template <>
|
||||||
components::basic::Grid* parse<components::basic::Grid> (boost::property_tree::ptree& root);
|
components::basic::Grid* parse<components::basic::Grid> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
components::basic::Inventory* parse<components::basic::Inventory> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
components::basic::InventoryItem* parse<components::basic::InventoryItem> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
components::basic::Sprite* parse<components::basic::Sprite> (boost::property_tree::ptree& root);
|
components::basic::Sprite* parse<components::basic::Sprite> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
@ -103,10 +110,7 @@ namespace storage {
|
|||||||
components::plants::Seed* parse<components::plants::Seed> (boost::property_tree::ptree& root);
|
components::plants::Seed* parse<components::plants::Seed> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
components::player::PlayerInventory* parse<components::player::PlayerInventory> (boost::property_tree::ptree& root);
|
components::player::Player* parse<components::player::Player> (boost::property_tree::ptree& root);
|
||||||
|
|
||||||
template <>
|
|
||||||
components::player::PlayerMovement* parse<components::player::PlayerMovement> (boost::property_tree::ptree& root);
|
|
||||||
|
|
||||||
|
|
||||||
/****** Graphics ******/
|
/****** Graphics ******/
|
||||||
|
Loading…
Reference in New Issue
Block a user