[BlockData] Added. [BlockWorkbench] Now keeps items stored inside.
This commit is contained in:
parent
b7d8c47e52
commit
9c16bfd264
84
include/core/Vector3.hpp
Normal file
84
include/core/Vector3.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: Vector3.hpp
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Created: 29/06/2018 06:57:12
|
||||
*
|
||||
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#ifndef VECTOR3_HPP_
|
||||
#define VECTOR3_HPP_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include "IntTypes.hpp"
|
||||
|
||||
template<typename T>
|
||||
class Vector3 {
|
||||
public:
|
||||
Vector3() = default;
|
||||
|
||||
Vector3(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
|
||||
|
||||
template<typename U>
|
||||
Vector3(const Vector3<U> &vector3) : x(vector3.x), y(vector3.y), z(vector3.z) {}
|
||||
|
||||
Vector3 operator+(const Vector3<T> &vector3) const { return Vector3{x + vector3.x, y + vector3.y, z + vector3.z}; }
|
||||
Vector3 operator-(const Vector3<T> &vector3) const { return Vector3{x - vector3.x, y - vector3.y, z - vector3.z}; }
|
||||
Vector3 operator*(T n) const { return Vector3{x * n, y * n, z * n}; }
|
||||
|
||||
Vector3 operator/(T n) const {
|
||||
if(n != 0) {
|
||||
return Vector3{x / n, y / n, z / n};
|
||||
} else {
|
||||
throw std::overflow_error("Divide by zero exception");
|
||||
}
|
||||
}
|
||||
|
||||
Vector3& operator=(T n) { x = n; y = n; z = n; return *this; }
|
||||
Vector3 &operator+=(const Vector3 &vector3) { *this = operator+(vector3); return *this; }
|
||||
Vector3 &operator-=(const Vector3 &vector3) { *this = operator-(vector3); return *this; }
|
||||
Vector3 &operator*=(T n) { *this = operator*(n); return *this; }
|
||||
Vector3 &operator/=(T n) { *this = operator/(n); return *this; }
|
||||
|
||||
bool operator==(const Vector3<T> &vector3) const { return x == vector3.x && y == vector3.y && z == vector3.z; }
|
||||
bool operator!=(const Vector3<T> &vector3) const { return !operator==(vector3); }
|
||||
|
||||
// Needed if Vector3 is used as a key in a std::map
|
||||
bool operator<(const Vector3<T> &vector3) const { return x < vector3.x && y <= vector3.y && z <= vector3.z; }
|
||||
bool operator>(const Vector3<T> &vector3) const { return x > vector3.x && y >= vector3.y && z >= vector3.z; }
|
||||
|
||||
T x;
|
||||
T y;
|
||||
T z;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> operator*(T n, Vector3<T> &vector3) { return vector3.operator*(n); }
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
struct hash<Vector3<T>> {
|
||||
size_t operator()(const Vector3<T>& vector3) const {
|
||||
std::hash<T> hash;
|
||||
auto h1 = hash(vector3.x);
|
||||
auto h2 = hash(vector3.y);
|
||||
auto h3 = hash(vector3.z);
|
||||
|
||||
return std::hash<T>{}(h1 ^ (h2 << h3) ^ h3);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using Vector3i = Vector3<int>;
|
||||
using Vector3u = Vector3<unsigned int>;
|
||||
using Vector3f = Vector3<float>;
|
||||
using Vector3d = Vector3<double>;
|
||||
|
||||
#endif // VECTOR3_HPP_
|
@ -20,7 +20,7 @@ class CraftingRecipe;
|
||||
|
||||
class CraftingWidget : public Widget {
|
||||
public:
|
||||
CraftingWidget(u16 width, u16 height, Widget *parent = nullptr);
|
||||
CraftingWidget(Inventory &craftingInventory, Widget *parent = nullptr);
|
||||
|
||||
void onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget);
|
||||
|
||||
@ -29,7 +29,7 @@ class CraftingWidget : public Widget {
|
||||
const ItemWidget *currentItemWidget() const { return m_craftingResultInventoryWidget.currentItemWidget() ? m_craftingResultInventoryWidget.currentItemWidget() : m_craftingInventoryWidget.currentItemWidget(); }
|
||||
|
||||
protected:
|
||||
Inventory m_craftingInventory;
|
||||
Inventory &m_craftingInventory;
|
||||
InventoryWidget m_craftingInventoryWidget{this};
|
||||
|
||||
Inventory m_craftingResultInventory{1, 1};
|
||||
|
@ -19,6 +19,9 @@
|
||||
class SmallCraftingWidget : public CraftingWidget {
|
||||
public:
|
||||
SmallCraftingWidget(Widget *parent = nullptr);
|
||||
|
||||
private:
|
||||
Inventory m_inventory{2, 2};
|
||||
};
|
||||
|
||||
#endif // SMALLCRAFTINGWIDGET_HPP_
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
class WorkbenchWidget : public Widget {
|
||||
public:
|
||||
WorkbenchWidget(Inventory &playerInventory, Inventory &hotbarInventory, Widget *parent = nullptr);
|
||||
WorkbenchWidget(Inventory &playerInventory, Inventory &hotbarInventory, Inventory &craftingInventory, Widget *parent = nullptr);
|
||||
|
||||
void onEvent(const SDL_Event &event) override;
|
||||
|
||||
@ -29,14 +29,14 @@ class WorkbenchWidget : public Widget {
|
||||
|
||||
Image m_background;
|
||||
|
||||
CraftingWidget m_craftingWidget{3, 3, this};
|
||||
|
||||
Inventory &m_playerInventory;
|
||||
InventoryWidget m_playerInventoryWidget{this};
|
||||
|
||||
Inventory &m_hotbarInventory;
|
||||
InventoryWidget m_hotbarInventoryWidget{this};
|
||||
|
||||
CraftingWidget m_craftingWidget;
|
||||
|
||||
MouseItemWidget m_mouseItemWidget{this};
|
||||
};
|
||||
|
||||
|
25
include/world/BlockData.hpp
Normal file
25
include/world/BlockData.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: BlockData.hpp
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Created: 29/06/2018 06:52:08
|
||||
*
|
||||
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#ifndef BLOCKDATA_HPP_
|
||||
#define BLOCKDATA_HPP_
|
||||
|
||||
#include "Inventory.hpp"
|
||||
|
||||
struct BlockData {
|
||||
BlockData(int width, int height) : inventory(width, height) {}
|
||||
|
||||
Inventory inventory;
|
||||
};
|
||||
|
||||
#endif // BLOCKDATA_HPP_
|
@ -19,12 +19,14 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Block.hpp"
|
||||
#include "BlockData.hpp"
|
||||
#include "ChunkBuilder.hpp"
|
||||
#include "ChunkLightmap.hpp"
|
||||
#include "IDrawable.hpp"
|
||||
#include "NonCopyable.hpp"
|
||||
#include "Shader.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "VertexBuffer.hpp"
|
||||
|
||||
class Chunk : public NonCopyable, public IDrawable {
|
||||
@ -46,6 +48,8 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
u32 getBlock(int x, int y, int z) const;
|
||||
void setBlock(int x, int y, int z, u32 id);
|
||||
|
||||
BlockData *getBlockData(int x, int y, int z);
|
||||
|
||||
s32 x() const { return m_x; }
|
||||
s32 y() const { return m_y; }
|
||||
s32 z() const { return m_z; }
|
||||
@ -97,6 +101,8 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
|
||||
u32 m_lastTick = 0;
|
||||
std::unordered_map<std::size_t, const Block&> m_tickingBlocks;
|
||||
|
||||
std::unordered_map<Vector3i, BlockData> m_blockData;
|
||||
};
|
||||
|
||||
#endif // CHUNK_HPP_
|
||||
|
@ -33,6 +33,8 @@ class World : public IDrawable {
|
||||
u32 getBlock(int x, int y, int z) const;
|
||||
void setBlock(int x, int y, int z, u32 id);
|
||||
|
||||
BlockData *getBlockData(int x, int y, int z);
|
||||
|
||||
// Render distance in chunks
|
||||
static const u16 renderDistance = 8;
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "CraftingWidget.hpp"
|
||||
#include "Registry.hpp"
|
||||
|
||||
CraftingWidget::CraftingWidget(u16 width, u16 height, Widget *parent) : Widget(parent), m_craftingInventory{width, height} {
|
||||
CraftingWidget::CraftingWidget(Inventory &craftingInventory, Widget *parent) : Widget(parent), m_craftingInventory{craftingInventory} {
|
||||
m_craftingInventoryWidget.init(m_craftingInventory);
|
||||
m_craftingInventoryWidget.setPosition(29, 16, 0);
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
#include "SmallCraftingWidget.hpp"
|
||||
|
||||
SmallCraftingWidget::SmallCraftingWidget(Widget *parent) : CraftingWidget(2, 2, parent) {
|
||||
SmallCraftingWidget::SmallCraftingWidget(Widget *parent) : CraftingWidget(m_inventory, parent) {
|
||||
m_craftingInventoryWidget.setPosition(97, 17, 0);
|
||||
m_craftingResultInventoryWidget.setPosition(153, 27, 0);
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
*/
|
||||
#include "WorkbenchWidget.hpp"
|
||||
|
||||
WorkbenchWidget::WorkbenchWidget(Inventory &playerInventory, Inventory &hotbarInventory, Widget *parent)
|
||||
: Widget(176, 166, parent), m_playerInventory(playerInventory), m_hotbarInventory(hotbarInventory)
|
||||
WorkbenchWidget::WorkbenchWidget(Inventory &playerInventory, Inventory &hotbarInventory, Inventory &craftingInventory, Widget *parent)
|
||||
: Widget(176, 166, parent), m_playerInventory(playerInventory), m_hotbarInventory(hotbarInventory), m_craftingWidget(craftingInventory, this)
|
||||
{
|
||||
m_background.load("texture-workbench");
|
||||
m_background.setClipRect(0, 0, 176, 166);
|
||||
|
@ -13,16 +13,23 @@
|
||||
*/
|
||||
#include "ApplicationStateStack.hpp"
|
||||
#include "BlockWorkbench.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "InventoryState.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "WorkbenchWidget.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
BlockWorkbench::BlockWorkbench() : Block(BlockType::Workbench, 77) {
|
||||
}
|
||||
|
||||
bool BlockWorkbench::onBlockActivated(const glm::ivec3 &, Player &player, World &) const {
|
||||
bool BlockWorkbench::onBlockActivated(const glm::ivec3 &position, Player &player, World &world) const {
|
||||
BlockData *data = world.getBlockData(position.x, position.y, position.z);
|
||||
if (!data)
|
||||
throw EXCEPTION("BlockWorkbench at (", position.x, position.y, position.z, ") has no inventory");
|
||||
|
||||
auto &inventoryState = ApplicationStateStack::getInstance().push<InventoryState>(&ApplicationStateStack::getInstance().top());
|
||||
inventoryState.setupWidget<WorkbenchWidget>(player.inventory(), player.hotbarInventory());
|
||||
inventoryState.setupWidget<WorkbenchWidget>(player.inventory(), player.hotbarInventory(), data->inventory);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,17 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
|
||||
else
|
||||
m_lightmap.removeLight(x, y, z);
|
||||
|
||||
if (type == BlockType::Workbench)
|
||||
m_blockData.emplace(Vector3i{x, y, z}, BlockData{3, 3});
|
||||
else if (type == BlockType::Furnace)
|
||||
m_blockData.emplace(Vector3i{x, y, z}, BlockData{1, 3});
|
||||
|
||||
if (m_data[x][y][z] == BlockType::Workbench || m_data[x][y][z] == BlockType::Furnace) {
|
||||
auto it = m_blockData.find(Vector3i{x, y, z});
|
||||
if (it != m_blockData.end())
|
||||
m_blockData.erase(it);
|
||||
}
|
||||
|
||||
m_data[x][y][z] = type;
|
||||
|
||||
m_isChanged = true;
|
||||
@ -95,6 +106,21 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
|
||||
if(z == depth - 1 && m_surroundingChunks[Back]) { m_surroundingChunks[Back]->m_isChanged = true; }
|
||||
}
|
||||
|
||||
BlockData *Chunk::getBlockData(int x, int y, int z) {
|
||||
if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->getBlockData(x + Chunk::width, y, z) : 0;
|
||||
if(x >= Chunk::width) return m_surroundingChunks[1] ? m_surroundingChunks[1]->getBlockData(x - Chunk::width, y, z) : 0;
|
||||
if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->getBlockData(x, y + Chunk::height, z) : 0;
|
||||
if(y >= Chunk::height) return m_surroundingChunks[5] ? m_surroundingChunks[5]->getBlockData(x, y - Chunk::height, z) : 0;
|
||||
if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getBlockData(x, y, z + Chunk::depth) : 0;
|
||||
if(z >= Chunk::depth) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getBlockData(x, y, z - Chunk::depth) : 0;
|
||||
|
||||
auto it = m_blockData.find(Vector3i{x, y, z});
|
||||
if (it == m_blockData.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void Chunk::updateNeighbours(int x, int y, int z) {
|
||||
int neighbours[7][3] = {
|
||||
{x, y, z},
|
||||
|
@ -168,3 +168,17 @@ void World::setBlock(int x, int y, int z, u32 id) {
|
||||
chunk->setBlock(x & (Chunk::width - 1), y & (Chunk::height - 1), z & (Chunk::depth - 1), id);
|
||||
}
|
||||
|
||||
BlockData *World::getBlockData(int x, int y, int z) {
|
||||
int cx = (x + Chunk::width * (m_width / 2)) / Chunk::width;
|
||||
int cy = (y + Chunk::height * (m_height / 2)) / Chunk::height;
|
||||
int cz = (z + Chunk::depth * (m_depth / 2)) / Chunk::depth;
|
||||
|
||||
if (cx < 0 || cx >= m_width || cy < 0 || cy >= m_height || cz < 0 || cz >= m_depth)
|
||||
return 0;
|
||||
|
||||
Chunk *chunk = m_chunks.at(cx + cy * m_width + cz * m_width * m_height).get();
|
||||
if (chunk)
|
||||
return chunk->getBlockData(x & (Chunk::width - 1), y & (Chunk::height - 1), z & (Chunk::depth - 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user