[BlockFurnace] Now displaying the corresponding texture when the furnace is active.

This commit is contained in:
Quentin Bazin 2018-06-29 09:48:37 +02:00
parent dd49aff276
commit 54ae2e2a68
10 changed files with 94 additions and 20 deletions

View File

@ -32,7 +32,7 @@ class Block {
virtual bool onBlockActivated(const glm::ivec3 &, Player &, World &) const { return false; }
virtual void onNeighbourUpdate(const glm::ivec3 &, const glm::ivec3 &, Chunk &) const {}
virtual glm::vec4 getTexCoords(int face) const;
virtual glm::vec4 getTexCoords(int face, u16 blockData) const;
u16 id() const { return m_id & 0xffff; }
u16 data() const { return (m_id >> 16) & 0xffff; }
@ -46,6 +46,8 @@ class Block {
bool canUpdate() const { return m_canUpdate; }
protected:
glm::vec4 getTexCoordsFromID(int textureID) const;
bool m_canUpdate = false;
private:

View File

@ -20,6 +20,8 @@ class BlockFurnace : public Block {
public:
BlockFurnace();
glm::vec4 getTexCoords(int face, u16 blockData) 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;
};

View File

@ -45,8 +45,10 @@ class Chunk : public NonCopyable, public IDrawable {
void update(Player &player, World &world);
u32 getBlock(int x, int y, int z) const;
void setBlock(int x, int y, int z, u32 id);
u16 getBlock(int x, int y, int z) const;
u16 getData(int x, int y, int z) const;
void setBlock(int x, int y, int z, u16 type);
void setData(int x, int y, int z, u16 data);
BlockData *getBlockData(int x, int y, int z);

View File

@ -30,8 +30,11 @@ class World : public IDrawable {
Chunk *getChunk(int cx, int cy, int cz) const;
u32 getBlock(int x, int y, int z) const;
void setBlock(int x, int y, int z, u32 id);
u16 getBlock(int x, int y, int z) const;
void setBlock(int x, int y, int z, u16 id);
u16 getData(int x, int y, int z) const;
void setData(int x, int y, int z, u16 id);
BlockData *getBlockData(int x, int y, int z);

View File

@ -69,7 +69,7 @@ void Cube::updateVertexBuffer(const Block &block) const {
};
for (u8 i = 0 ; i < 6 ; ++i) {
const glm::vec4 &blockTexCoords = block.getTexCoords(i);
const glm::vec4 &blockTexCoords = block.getTexCoords(i, 0);
float faceTexCoords[2 * 4] = {
blockTexCoords.x, blockTexCoords.w,
blockTexCoords.z, blockTexCoords.w,

View File

@ -18,7 +18,7 @@ Block::Block(u32 id, u32 textureID) {
m_textureID = textureID;
}
glm::vec4 Block::getTexCoords(int face) const {
glm::vec4 Block::getTexCoords(int face, u16) const {
// 0 -> right
// 1 -> left
// 2 -> bottom
@ -44,12 +44,10 @@ glm::vec4 Block::getTexCoords(int face) const {
if (face == 3 || face == 2) textureID = m_textureID + 2;
}
// Furnace
if (m_id == BlockType::Furnace) {
if (face == 1 || face == 4 || face == 5) textureID = m_textureID + 2;
if (face == 3 || face == 2) textureID = m_textureID + 3;
}
return getTexCoordsFromID(textureID);
}
glm::vec4 Block::getTexCoordsFromID(int textureID) const {
// FIXME: HARDCODED VALUES
const u16 textureWidth = 256;
const u16 textureHeight = 464;

View File

@ -23,6 +23,17 @@ BlockFurnace::BlockFurnace() : Block(BlockType::Furnace, 164) {
m_canUpdate = true;
}
glm::vec4 BlockFurnace::getTexCoords(int face, u16 blockData) const {
u32 texID = textureID();
if (face == 1 || face == 4 || face == 5) texID = 166;
if (face == 3 || face == 2) texID = 167;
if (face == 0 && blockData)
texID = 165;
return getTexCoordsFromID(texID);
}
bool BlockFurnace::onBlockActivated(const glm::ivec3 &blockPosition, Player &player, World &world) const {
BlockData *data = world.getBlockData(blockPosition.x, blockPosition.y, blockPosition.z);
if (!data)
@ -50,13 +61,18 @@ void BlockFurnace::onTick(const glm::ivec3 &blockPosition, Player &, Chunk &, Wo
data->inventory.setStack(2, 0, fuelStack.item().id(), fuelStack.amount() - 1);
ticksRemaining = fuelStack.item().burnTime();
currentBurnTime = fuelStack.item().burnTime();
world.setData(blockPosition.x, blockPosition.y, blockPosition.z, 1);
}
else if (ticksRemaining > 0 && (!outputStack.amount() || !outputStack.item().id() || outputStack.item().id() == ItemType::IronIngot)) { // FIXME
--ticksRemaining;
++itemProgress;
if (inputStack.amount())
++itemProgress;
else
itemProgress = 0;
}
else if (ticksRemaining == 0) {
currentBurnTime = 0;
world.setData(blockPosition.x, blockPosition.y, blockPosition.z, 0);
}
if (itemProgress >= 200) {

View File

@ -42,19 +42,29 @@ void Chunk::update(Player &player, World &world) {
}
}
u32 Chunk::getBlock(int x, int y, int z) const {
u16 Chunk::getBlock(int x, int y, int z) const {
if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->getBlock(x + Chunk::width, y, z) : 0;
if(x >= Chunk::width) return m_surroundingChunks[1] ? m_surroundingChunks[1]->getBlock(x - Chunk::width, y, z) : 0;
if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->getBlock(x, y + Chunk::height, z) : 0;
if(y >= Chunk::height) return m_surroundingChunks[5] ? m_surroundingChunks[5]->getBlock(x, y - Chunk::height, z) : 0;
if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getBlock(x, y, z + Chunk::depth) : 0;
if(z >= Chunk::depth) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getBlock(x, y, z - Chunk::depth) : 0;
return m_data[x][y][z];
return m_data[x][y][z] & 0xffff;
}
u16 Chunk::getData(int x, int y, int z) const {
if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->getData(x + Chunk::width, y, z) : 0;
if(x >= Chunk::width) return m_surroundingChunks[1] ? m_surroundingChunks[1]->getData(x - Chunk::width, y, z) : 0;
if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->getData(x, y + Chunk::height, z) : 0;
if(y >= Chunk::height) return m_surroundingChunks[5] ? m_surroundingChunks[5]->getData(x, y - Chunk::height, z) : 0;
if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getData(x, y, z + Chunk::depth) : 0;
if(z >= Chunk::depth) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getData(x, y, z - Chunk::depth) : 0;
return (m_data[x][y][z] >> 16) & 0xffff;
}
// #include "Debug.hpp"
void Chunk::setBlock(int x, int y, int z, u32 type) {
void Chunk::setBlock(int x, int y, int z, u16 type) {
if(x < 0) { if(m_surroundingChunks[0]) m_surroundingChunks[0]->setBlock(x + Chunk::width, y, z, type); return; }
if(x >= Chunk::width) { if(m_surroundingChunks[1]) m_surroundingChunks[1]->setBlock(x - Chunk::width, y, z, type); return; }
if(y < 0) { if(m_surroundingChunks[4]) m_surroundingChunks[4]->setBlock(x, y + Chunk::height, z, type); return; }
@ -104,6 +114,20 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
if(z == depth - 1 && m_surroundingChunks[Back]) { m_surroundingChunks[Back]->m_isChanged = true; }
}
void Chunk::setData(int x, int y, int z, u16 data) {
if(x < 0) { if(m_surroundingChunks[0]) m_surroundingChunks[0]->setData(x + Chunk::width, y, z, data); return; }
if(x >= Chunk::width) { if(m_surroundingChunks[1]) m_surroundingChunks[1]->setData(x - Chunk::width, y, z, data); return; }
if(y < 0) { if(m_surroundingChunks[4]) m_surroundingChunks[4]->setData(x, y + Chunk::height, z, data); return; }
if(y >= Chunk::height) { if(m_surroundingChunks[5]) m_surroundingChunks[5]->setData(x, y - Chunk::height, z, data); return; }
if(z < 0) { if(m_surroundingChunks[2]) m_surroundingChunks[2]->setData(x, y, z + Chunk::depth, data); return; }
if(z >= Chunk::depth) { if(m_surroundingChunks[3]) m_surroundingChunks[3]->setData(x, y, z - Chunk::depth, data); return; }
m_data[x][y][z] &= 0xffff;
m_data[x][y][z] |= (data << 16);
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;

View File

@ -92,7 +92,7 @@ std::size_t ChunkBuilder::buildChunk(const Chunk &chunk, const VertexBuffer &vbo
void ChunkBuilder::addFace(u8 x, u8 y, u8 z, u8 i, const Chunk &chunk, const Block *block, const Block *surroundingBlock) {
// Skip hidden faces
if(surroundingBlock && surroundingBlock->id()
&& (surroundingBlock->isOpaque() || (block->id() == surroundingBlock->id() && block->id() != 4)))
&& (surroundingBlock->isOpaque() || (block->id() == surroundingBlock->id() && block->id() != BlockType::Leaves)))
return;
static glm::vec3 a, b, c, v1, v2, normal;
@ -117,7 +117,7 @@ void ChunkBuilder::addFace(u8 x, u8 y, u8 z, u8 i, const Chunk &chunk, const Blo
// Computing face normal (already normalized because cubeCoords are normalized)
normal = glm::cross(v1, v2);
const glm::vec4 &blockTexCoords = block->getTexCoords(i);
const glm::vec4 &blockTexCoords = block->getTexCoords(i, chunk.getData(x, y, z));
float faceTexCoords[2 * 4] = {
blockTexCoords.x, blockTexCoords.w,
blockTexCoords.z, blockTexCoords.w,

View File

@ -141,7 +141,7 @@ Chunk *World::getChunk(int cx, int cy, int cz) const {
return m_chunks.at(cx + cy * m_width + cz * m_width * m_height).get();
}
u32 World::getBlock(int x, int y, int z) const {
u16 World::getBlock(int x, int y, int z) const {
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;
@ -155,7 +155,7 @@ u32 World::getBlock(int x, int y, int z) const {
return 0;
}
void World::setBlock(int x, int y, int z, u32 id) {
void World::setBlock(int x, int y, int z, u16 id) {
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;
@ -168,6 +168,33 @@ 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);
}
u16 World::getData(int x, int y, int z) const {
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->getData(x & (Chunk::width - 1), y & (Chunk::height - 1), z & (Chunk::depth - 1));
return 0;
}
void World::setData(int x, int y, int z, u16 id) {
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;
Chunk *chunk = m_chunks.at(cx + cy * m_width + cz * m_width * m_height).get();
if (chunk)
chunk->setData(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;