[BlockFurnace] Now able to smelt iron ore into ingots, using coal as fuel.
This commit is contained in:
parent
da0877f515
commit
a258fde36a
@ -20,5 +20,7 @@ typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned long u32;
|
||||
typedef signed long s32;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed long long s64;
|
||||
|
||||
#endif // INTTYPES_HPP_
|
||||
|
@ -24,13 +24,13 @@
|
||||
class Registry {
|
||||
public:
|
||||
template<typename T, typename... Args>
|
||||
auto registerBlock(Args &&...args) -> typename std::enable_if<std::is_base_of<Block, T>::value>::type {
|
||||
m_blocks.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
|
||||
auto registerBlock(Args &&...args) -> typename std::enable_if<std::is_base_of<Block, T>::value, Block&>::type {
|
||||
return *m_blocks.emplace_back(std::make_unique<T>(std::forward<Args>(args)...)).get();
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
auto registerItem(Args &&...args) -> typename std::enable_if<std::is_base_of<Item, T>::value>::type {
|
||||
m_items.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
|
||||
auto registerItem(Args &&...args) -> typename std::enable_if<std::is_base_of<Item, T>::value, Item&>::type {
|
||||
return *m_items.emplace_back(std::make_unique<T>(std::forward<Args>(args)...)).get();
|
||||
}
|
||||
|
||||
void registerBlocks();
|
||||
|
@ -14,11 +14,12 @@
|
||||
#ifndef FURNACEWIDGET_HPP_
|
||||
#define FURNACEWIDGET_HPP_
|
||||
|
||||
#include "BlockData.hpp"
|
||||
#include "InventoryWidget.hpp"
|
||||
|
||||
class FurnaceWidget : public Widget {
|
||||
public:
|
||||
FurnaceWidget(Inventory &playerInventory, Inventory &hotbarInventory, Widget *parent = nullptr);
|
||||
FurnaceWidget(Inventory &playerInventory, Inventory &hotbarInventory, BlockData &blockData, Widget *parent = nullptr);
|
||||
|
||||
void onEvent(const SDL_Event &event) override;
|
||||
|
||||
@ -35,6 +36,12 @@ class FurnaceWidget : public Widget {
|
||||
Inventory &m_hotbarInventory;
|
||||
InventoryWidget m_hotbarInventoryWidget{this};
|
||||
|
||||
InventoryWidget m_inputInventoryWidget{this};
|
||||
InventoryWidget m_outputInventoryWidget{this};
|
||||
InventoryWidget m_fuelInventoryWidget{this};
|
||||
|
||||
BlockData &m_blockData;
|
||||
|
||||
MouseItemWidget m_mouseItemWidget{this};
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@ class InventoryWidget : public Widget {
|
||||
public:
|
||||
InventoryWidget(Widget *parent = nullptr) : Widget(parent) {}
|
||||
|
||||
void init(Inventory &inventory);
|
||||
void init(Inventory &inventory, unsigned int offset = 0, unsigned int size = 0);
|
||||
|
||||
void onMouseEvent(const SDL_Event &event, MouseItemWidget &mouseItemWidget, bool isReadOnly = false);
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace BlockType {
|
||||
Glowstone = 12,
|
||||
Workbench = 13,
|
||||
Furnace = 14,
|
||||
IronOre = 15,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,17 @@ class Item {
|
||||
u32 textureID() const { return m_textureID; }
|
||||
|
||||
bool isBlock() const { return m_isBlock; }
|
||||
bool isFuel() const { return m_isFuel; }
|
||||
void setIsFuel(bool isFuel) { m_isFuel = isFuel; }
|
||||
|
||||
u16 burnTime() const { return m_burnTime; }
|
||||
void setBurnTime(u16 burnTime) { m_burnTime = burnTime; }
|
||||
|
||||
protected:
|
||||
bool m_isBlock = false;
|
||||
bool m_isFuel = false;
|
||||
|
||||
u16 m_burnTime = 0;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
@ -31,13 +31,16 @@ namespace ItemType {
|
||||
Glowstone = 12,
|
||||
Workbench = 13,
|
||||
Furnace = 14,
|
||||
IronOre = 15,
|
||||
|
||||
Stick = 15,
|
||||
StoneAxe = 16,
|
||||
StoneHoe = 17,
|
||||
StonePickaxe = 18,
|
||||
StoneShovel = 19,
|
||||
StoneSword = 20,
|
||||
Stick = 16,
|
||||
StoneAxe = 17,
|
||||
StoneHoe = 18,
|
||||
StonePickaxe = 19,
|
||||
StoneShovel = 20,
|
||||
StoneSword = 21,
|
||||
Coal = 22,
|
||||
IronIngot = 23
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ struct BlockData {
|
||||
BlockData(int width, int height) : inventory(width, height) {}
|
||||
|
||||
Inventory inventory;
|
||||
|
||||
u64 data = 0;
|
||||
};
|
||||
|
||||
#endif // BLOCKDATA_HPP_
|
||||
|
@ -20,7 +20,7 @@ class BlockFurnace : public Block {
|
||||
public:
|
||||
BlockFurnace();
|
||||
|
||||
bool onBlockActivated(const glm::ivec3 &position, Player &player, World &world) const override;
|
||||
bool onBlockActivated(const glm::ivec3 &blockPosition, Player &player, World &world) const override;
|
||||
void onTick(const glm::ivec3 &blockPosition, Player &player, Chunk &chunk, World &world) const override;
|
||||
};
|
||||
|
||||
|
@ -36,6 +36,7 @@ void Registry::registerBlocks() {
|
||||
registerBlock<Block>(BlockType::Glowstone, 218);
|
||||
registerBlock<BlockWorkbench>();
|
||||
registerBlock<BlockFurnace>();
|
||||
registerBlock<Block>(BlockType::IronOre, 254);
|
||||
}
|
||||
|
||||
void Registry::registerItems() {
|
||||
@ -54,6 +55,7 @@ void Registry::registerItems() {
|
||||
registerItem<ItemBlock>(ItemType::Glowstone, BlockType::Glowstone, "Glowstone");
|
||||
registerItem<ItemBlock>(ItemType::Workbench, BlockType::Workbench, "Workbench");
|
||||
registerItem<ItemBlock>(ItemType::Furnace, BlockType::Furnace, "Furnace");
|
||||
registerItem<ItemBlock>(ItemType::IronOre, BlockType::IronOre, "Iron Ore");
|
||||
|
||||
registerItem<Item>(ItemType::Stick, 324, "Stick");
|
||||
registerItem<Item>(ItemType::StoneAxe, 325, "Stone Axe");
|
||||
@ -62,6 +64,12 @@ void Registry::registerItems() {
|
||||
registerItem<Item>(ItemType::StoneShovel, 328, "Stone Shovel");
|
||||
registerItem<Item>(ItemType::StoneSword, 329, "Stone Sword");
|
||||
|
||||
Item &itemCoal = registerItem<Item>(ItemType::Coal, 111, "Coal");
|
||||
itemCoal.setIsFuel(true);
|
||||
itemCoal.setBurnTime(1600);
|
||||
|
||||
registerItem<Item>(ItemType::IronIngot, 232, "Iron Ingot");
|
||||
|
||||
// FIXME: Move this to Application or load from XML file
|
||||
registerRecipes();
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
*/
|
||||
#include "FurnaceWidget.hpp"
|
||||
|
||||
FurnaceWidget::FurnaceWidget(Inventory &playerInventory, Inventory &hotbarInventory, Widget *parent)
|
||||
: Widget(176, 166, parent), m_playerInventory(playerInventory), m_hotbarInventory(hotbarInventory)
|
||||
FurnaceWidget::FurnaceWidget(Inventory &playerInventory, Inventory &hotbarInventory, BlockData &blockData, Widget *parent)
|
||||
: Widget(176, 166, parent), m_playerInventory(playerInventory), m_hotbarInventory(hotbarInventory), m_blockData(blockData)
|
||||
{
|
||||
m_background.load("texture-furnace");
|
||||
m_background.setClipRect(0, 0, 176, 166);
|
||||
@ -24,19 +24,34 @@ FurnaceWidget::FurnaceWidget(Inventory &playerInventory, Inventory &hotbarInvent
|
||||
|
||||
m_hotbarInventoryWidget.init(m_hotbarInventory);
|
||||
m_hotbarInventoryWidget.setPosition(7, 141, 0);
|
||||
|
||||
m_inputInventoryWidget.setPosition(55, 16, 0);
|
||||
m_outputInventoryWidget.setPosition(115, 34, 0);
|
||||
m_fuelInventoryWidget.setPosition(55, 52, 0);
|
||||
}
|
||||
|
||||
void FurnaceWidget::onEvent(const SDL_Event &event) {
|
||||
m_playerInventoryWidget.onMouseEvent(event, m_mouseItemWidget);
|
||||
m_hotbarInventoryWidget.onMouseEvent(event, m_mouseItemWidget);
|
||||
|
||||
m_inputInventoryWidget.onMouseEvent(event, m_mouseItemWidget);
|
||||
m_outputInventoryWidget.onMouseEvent(event, m_mouseItemWidget);
|
||||
m_fuelInventoryWidget.onMouseEvent(event, m_mouseItemWidget);
|
||||
|
||||
m_mouseItemWidget.onEvent(event);
|
||||
}
|
||||
|
||||
void FurnaceWidget::update() {
|
||||
m_inputInventoryWidget.init(m_blockData.inventory, 0, 1);
|
||||
m_outputInventoryWidget.init(m_blockData.inventory, 1, 1);
|
||||
m_fuelInventoryWidget.init(m_blockData.inventory, 2, 1);
|
||||
|
||||
const ItemWidget *currentItemWidget = nullptr;
|
||||
if ((currentItemWidget = m_playerInventoryWidget.currentItemWidget())
|
||||
|| (currentItemWidget = m_hotbarInventoryWidget.currentItemWidget()))
|
||||
|| (currentItemWidget = m_hotbarInventoryWidget.currentItemWidget())
|
||||
|| (currentItemWidget = m_inputInventoryWidget.currentItemWidget())
|
||||
|| (currentItemWidget = m_outputInventoryWidget.currentItemWidget())
|
||||
|| (currentItemWidget = m_fuelInventoryWidget.currentItemWidget()))
|
||||
m_mouseItemWidget.update(currentItemWidget);
|
||||
else
|
||||
m_mouseItemWidget.update(nullptr);
|
||||
@ -50,6 +65,10 @@ void FurnaceWidget::draw(RenderTarget &target, RenderStates states) const {
|
||||
target.draw(m_playerInventoryWidget, states);
|
||||
target.draw(m_hotbarInventoryWidget, states);
|
||||
|
||||
target.draw(m_inputInventoryWidget, states);
|
||||
target.draw(m_outputInventoryWidget, states);
|
||||
target.draw(m_fuelInventoryWidget, states);
|
||||
|
||||
target.draw(m_mouseItemWidget, states);
|
||||
}
|
||||
|
||||
|
@ -13,15 +13,15 @@
|
||||
*/
|
||||
#include "InventoryWidget.hpp"
|
||||
|
||||
void InventoryWidget::init(Inventory &inventory) {
|
||||
void InventoryWidget::init(Inventory &inventory, unsigned int offset, unsigned int size) {
|
||||
m_itemWidgets.clear();
|
||||
|
||||
for (u16 y = 0 ; y < inventory.height() ; ++y) {
|
||||
for (u16 x = 0 ; x < inventory.width() ; ++x) {
|
||||
ItemWidget &widget = m_itemWidgets.emplace_back(inventory, x, y, this);
|
||||
widget.update();
|
||||
widget.setPosition(x * 18, y * 18, 0);
|
||||
}
|
||||
// for (u16 y = 0 ; y < inventory.height() ; ++y) {
|
||||
// for (u16 x = 0 ; x < inventory.width() ; ++x) {
|
||||
for (u16 i = 0 ; i < (size > 0 ? size : inventory.width() * inventory.height()) ; ++i) {
|
||||
ItemWidget &widget = m_itemWidgets.emplace_back(inventory, (i + offset) % inventory.width(), (i + offset) / inventory.width(), this);
|
||||
widget.update();
|
||||
widget.setPosition((i % inventory.width()) * 18, (i / inventory.width()) * 18, 0);
|
||||
}
|
||||
|
||||
m_width = inventory.width() * 18;
|
||||
|
@ -44,6 +44,8 @@ GameState::GameState() {
|
||||
m_player.inventory().addStack(ItemType::StonePickaxe, 1);
|
||||
m_player.inventory().addStack(ItemType::StoneShovel, 1);
|
||||
m_player.inventory().addStack(ItemType::StoneSword, 1);
|
||||
m_player.inventory().addStack(ItemType::IronOre, 64);
|
||||
m_player.inventory().addStack(ItemType::Coal, 64);
|
||||
|
||||
m_projectionMatrix = glm::perspective(45.0f, (float)SCREEN_WIDTH / SCREEN_HEIGHT, DIST_NEAR, DIST_FAR);
|
||||
|
||||
|
@ -13,19 +13,57 @@
|
||||
*/
|
||||
#include "ApplicationStateStack.hpp"
|
||||
#include "BlockFurnace.hpp"
|
||||
#include "Exception.hpp"
|
||||
#include "FurnaceWidget.hpp"
|
||||
#include "InventoryState.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
BlockFurnace::BlockFurnace() : Block(BlockType::Furnace, 164) {
|
||||
m_canUpdate = true;
|
||||
}
|
||||
|
||||
bool BlockFurnace::onBlockActivated(const glm::ivec3 &, Player &player, World &) const {
|
||||
bool BlockFurnace::onBlockActivated(const glm::ivec3 &blockPosition, Player &player, World &world) const {
|
||||
BlockData *data = world.getBlockData(blockPosition.x, blockPosition.y, blockPosition.z);
|
||||
if (!data)
|
||||
throw EXCEPTION("BlockFurnace at (", blockPosition.x, blockPosition.y, blockPosition.z, ") has no inventory");
|
||||
|
||||
auto &inventoryState = ApplicationStateStack::getInstance().push<InventoryState>(&ApplicationStateStack::getInstance().top());
|
||||
inventoryState.setupWidget<FurnaceWidget>(player.inventory(), player.hotbarInventory());
|
||||
inventoryState.setupWidget<FurnaceWidget>(player.inventory(), player.hotbarInventory(), *data);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlockFurnace::onTick(const glm::ivec3 &blockPosition, Player &player, Chunk &chunk, World &world) const {
|
||||
void BlockFurnace::onTick(const glm::ivec3 &blockPosition, Player &, Chunk &, World &world) const {
|
||||
BlockData *data = world.getBlockData(blockPosition.x, blockPosition.y, blockPosition.z);
|
||||
if (!data)
|
||||
throw EXCEPTION("BlockFurnace at (", blockPosition.x, blockPosition.y, blockPosition.z, ") has no inventory");
|
||||
|
||||
const ItemStack &inputStack = data->inventory.getStack(0, 0);
|
||||
const ItemStack &outputStack = data->inventory.getStack(1, 0);
|
||||
const ItemStack &fuelStack = data->inventory.getStack(2, 0);
|
||||
|
||||
u16 ticksRemaining = data->data & 0xffff;
|
||||
u16 itemProgress = (data->data >> 16) & 0xffff;
|
||||
|
||||
DEBUG((int)ticksRemaining, (int)itemProgress, fuelStack.amount());
|
||||
|
||||
if (ticksRemaining == 0 && fuelStack.amount() && inputStack.amount() && inputStack.item().id() == ItemType::IronOre) {
|
||||
data->inventory.setStack(2, 0, fuelStack.item().id(), fuelStack.amount() - 1);
|
||||
ticksRemaining = fuelStack.item().burnTime();
|
||||
}
|
||||
else if (ticksRemaining > 0 && (!outputStack.amount() || !outputStack.item().id() || outputStack.item().id() == ItemType::IronIngot)) { // FIXME
|
||||
--ticksRemaining;
|
||||
++itemProgress;
|
||||
}
|
||||
|
||||
if (itemProgress > 200) {
|
||||
itemProgress = 0;
|
||||
if (inputStack.item().id() == ItemType::IronOre && inputStack.amount()) {
|
||||
data->inventory.setStack(0, 0, inputStack.item().id(), inputStack.amount() - 1);
|
||||
data->inventory.setStack(1, 0, ItemType::IronIngot);
|
||||
}
|
||||
}
|
||||
|
||||
data->data = ticksRemaining | (itemProgress << 16);
|
||||
}
|
||||
|
||||
|
@ -24,15 +24,7 @@ Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
||||
}
|
||||
|
||||
void Chunk::update(Player &player, World &world) {
|
||||
if (!m_isChanged) return;
|
||||
|
||||
m_isChanged = false;
|
||||
|
||||
m_lightmap.updateLights();
|
||||
|
||||
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
|
||||
|
||||
if (m_lastTick < GameClock::getTicks() / 50) {
|
||||
if (!m_tickingBlocks.empty() && m_lastTick < GameClock::getTicks() / 50) {
|
||||
m_lastTick = GameClock::getTicks() / 50;
|
||||
|
||||
for (auto &it : m_tickingBlocks) {
|
||||
@ -42,6 +34,12 @@ void Chunk::update(Player &player, World &world) {
|
||||
it.second.onTick(glm::ivec3{x + m_x * width, y + m_y * height, z + m_z * depth}, player, *this, world);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_isChanged) {
|
||||
m_isChanged = false;
|
||||
m_lightmap.updateLights();
|
||||
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Chunk::getBlock(int x, int y, int z) const {
|
||||
@ -84,7 +82,7 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
|
||||
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});
|
||||
m_blockData.emplace(Vector3i{x, y, z}, BlockData{3, 1});
|
||||
|
||||
if (m_data[x][y][z] == BlockType::Workbench || m_data[x][y][z] == BlockType::Furnace) {
|
||||
auto it = m_blockData.find(Vector3i{x, y, z});
|
||||
|
Loading…
x
Reference in New Issue
Block a user