Skip to content

Commit

Permalink
Blocks can now be rotated depending on the player direction.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Mar 1, 2020
1 parent c1becd9 commit ec7ef36
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 19 deletions.
10 changes: 9 additions & 1 deletion client/source/hud/BlockCursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,15 @@ void BlockCursor::onEvent(const SDL_Event &event, const Hotbar &hotbar) {
if (!boundingBox.intersects(playerBoundingBox)) {
m_world.setBlock(x, y, z, hotbar.currentItem());

m_client.sendPlayerPlaceBlock(x, y, z, hotbar.currentItem());
u32 block = hotbar.currentItem();
if (newBlock.isRotatable()) {
u16 data = m_player.getOppositeDirection() & 0x3;
m_world.setData(x, y, z, data);

block |= data << 16;
}

m_client.sendPlayerPlaceBlock(x, y, z, block);

const ItemStack &currentStack = m_player.inventory().getStack(hotbar.cursorPos(), 0);
m_player.inventory().setStack(hotbar.cursorPos(), 0, currentStack.amount() > 1 ? currentStack.item().stringID() : "", currentStack.amount() - 1);
Expand Down
2 changes: 1 addition & 1 deletion client/source/hud/DebugOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void DebugOverlay::update() {
stream << "cy: " << (py & -CHUNK_DEPTH) / CHUNK_DEPTH << " | ";
stream << "cz: " << (pz & -CHUNK_HEIGHT) / CHUNK_HEIGHT;
stream << '\n';
stream << "dir: " << direction << " (" << m_player.viewAngleH() << ")";
stream << "dir: " << direction << " (" << m_player.cameraYaw() << ")";
stream << '\n';
stream << "Loaded chunks: " << m_world.loadedChunkCount();

Expand Down
22 changes: 19 additions & 3 deletions client/source/world/ChunkBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@
#include "Registry.hpp"
#include "TextureAtlas.hpp"

// Same order as enum BlockFace in TilesDef.hpp
static const float cubeCoords[6 * 4 * 3] = {
// Same order as enum BlockFace in TilesDef.hpp

// West
0, 1, 0,
0, 0, 0,
Expand Down Expand Up @@ -170,8 +169,25 @@ inline void ChunkBuilder::addFace(u8 x, u8 y, u8 z, u8 i, const ClientChunk &chu
// Computing face normal (already normalized because vertexCoords are normalized)
normal = glm::cross(v1, v2);

u8 faceID = i;
if (block->isRotatable()) {
u8 orientation = chunk.getData(x, y, z) & 0x3;
if (faceID < 4) {
u8 faceToAngle[4] = {0, 2, 1, 3};
u8 angleToFace[4] = {BlockFace::West, BlockFace::South, BlockFace::East, BlockFace::North};

if (orientation == BlockFace::South)
faceID = angleToFace[(faceToAngle[faceID] + 1) % 4];
else if (orientation == BlockFace::West) // FIXME: Find why East and West are inverted
faceID = angleToFace[(faceToAngle[faceID] + 2) % 4];
else if (orientation == BlockFace::North)
faceID = angleToFace[(faceToAngle[faceID] + 3) % 4];
}
}

const BlockData *blockData = chunk.getBlockData(x, y, z);
const gk::FloatRect &blockTexCoords = m_textureAtlas.getTexCoords(block->tiles().getTextureForFace(i, blockData ? blockData->useAltTiles : false));
const std::string &texture = block->tiles().getTextureForFace(faceID, blockData ? blockData->useAltTiles : false);
const gk::FloatRect &blockTexCoords = m_textureAtlas.getTexCoords(texture);
float faceTexCoords[2 * 4] = {
blockTexCoords.x, blockTexCoords.y + blockTexCoords.sizeY,
blockTexCoords.x + blockTexCoords.sizeX, blockTexCoords.y + blockTexCoords.sizeY,
Expand Down
5 changes: 5 additions & 0 deletions client/source/world/ClientPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ u8 ClientPlayer::getDirection() const {
}
}

u8 ClientPlayer::getOppositeDirection() const {
u8 direction = getDirection();
return (direction % 2 == 0) ? direction + 1 : direction - 1;
}

void ClientPlayer::updateDir() {
double ch = cos(m_viewAngleH * RADIANS_PER_DEGREES);
double sh = sin(m_viewAngleH * RADIANS_PER_DEGREES);
Expand Down
3 changes: 2 additions & 1 deletion client/source/world/ClientPlayer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ class ClientPlayer : public Player {
void turnViewV(double angle);

// West, East, South, North
// Same order as enum BlockFace in TilesDef.hpp
u8 getDirection() const;
double viewAngleH() const { return m_viewAngleH; }
u8 getOppositeDirection() const;

void move(double direction);

Expand Down
6 changes: 3 additions & 3 deletions client/source/world/ClientWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ void ClientWorld::receiveChunkData(sf::Packet &packet) {
for (u16 z = 0 ; z < CHUNK_HEIGHT ; ++z) {
for (u16 y = 0 ; y < CHUNK_DEPTH ; ++y) {
for (u16 x = 0 ; x < CHUNK_WIDTH ; ++x) {
u16 block;
u32 block;
u8 light;

packet >> block >> light;

chunk->setBlockRaw(x, y, z, block & 0xffff);
// chunk->setData(x, y, z, block >> 16);
chunk->setData(x, y, z, block >> 16);
chunk->lightmap().setLightData(x, y, z, light);
}
}
Expand Down Expand Up @@ -213,7 +213,7 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
// an issue at larger coordinates, because the precision of floats
// quickly degrades as the numbers grow, with a random wobbling being
// very noticeable at e.g. coordinates >= 65536 or so, and the waving
// leaves effect being very jerky in conparison with the effect near the
// leaves effect being very jerky in comparison with the effect near the
// origin.
//
// To gain rendering precision, we subtract the camera position from the
Expand Down
12 changes: 6 additions & 6 deletions common/source/core/TilesDef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ const std::string &TilesDef::getTextureForFace(u8 face, bool useAltTiles) const
static constexpr u8 faceToIndex[nSizes][nFaces] = {
// Same order as enum BlockFace in TilesDef.hpp,
// namely: West, East, South, North, Bottom, Top
{ 0, 0, 0, 0, 0, 0, }, // for size = 1
{ 1, 1, 1, 1, 0, 0, }, // for size = 2
{ 2, 2, 2, 2, 1, 0, }, // for size = 3
{ 2, 3, 3, 3, 1, 0, }, // for size = 4
{ 2, 3, 4, 4, 1, 0, }, // for size = 5
{ 2, 3, 4, 5, 1, 0, }, // for size = 6
{0, 0, 0, 0, 0, 0}, // for size = 1
{1, 1, 1, 1, 0, 0}, // for size = 2
{2, 2, 2, 2, 1, 0}, // for size = 3
{2, 3, 3, 3, 1, 0}, // for size = 4
{2, 3, 4, 4, 1, 0}, // for size = 5
{2, 3, 4, 5, 1, 0}, // for size = 6
};

u8 index = faceToIndex[size <= nSizes ? size - 1 : nSizes - 1][face];
Expand Down
6 changes: 4 additions & 2 deletions common/source/world/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ void Block::serialize(sf::Packet &packet) const {
<< m_boundingBox.x << m_boundingBox.y << m_boundingBox.z
<< m_boundingBox.sizeX << m_boundingBox.sizeY << m_boundingBox.sizeZ
<< m_isLightSource << m_canUpdate << m_canBeActivated
<< m_colorMultiplier.r << m_colorMultiplier.g << m_colorMultiplier.b << m_colorMultiplier.a;
<< m_colorMultiplier.r << m_colorMultiplier.g << m_colorMultiplier.b << m_colorMultiplier.a
<< m_isRotatable;
}

void Block::deserialize(sf::Packet &packet) {
Expand All @@ -61,7 +62,8 @@ void Block::deserialize(sf::Packet &packet) {
>> m_boundingBox.x >> m_boundingBox.y >> m_boundingBox.z
>> m_boundingBox.sizeX >> m_boundingBox.sizeY >> m_boundingBox.sizeZ
>> m_isLightSource >> m_canUpdate >> m_canBeActivated
>> m_colorMultiplier.r >> m_colorMultiplier.g >> m_colorMultiplier.b >> m_colorMultiplier.a;
>> m_colorMultiplier.r >> m_colorMultiplier.g >> m_colorMultiplier.b >> m_colorMultiplier.a
>> m_isRotatable;

m_id = id;
m_drawType = BlockDrawType(drawType);
Expand Down
5 changes: 5 additions & 0 deletions common/source/world/Block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class Block : public ISerializable {
const gk::Color &colorMultiplier() const { return m_colorMultiplier; }
void setColorMultiplier(const gk::Color &colorMultiplier) { m_colorMultiplier = colorMultiplier; }

bool isRotatable() const { return m_isRotatable; }
void setRotatable(bool isRotatable) { m_isRotatable = isRotatable; }

protected:
glm::vec4 getTexCoordsFromID(int textureID) const;

Expand Down Expand Up @@ -129,6 +132,8 @@ class Block : public ISerializable {
bool m_isLightSource = false;

gk::Color m_colorMultiplier = gk::Color::White;

bool m_isRotatable = false;
};

#endif // BLOCK_HPP_
1 change: 1 addition & 0 deletions mods/default/furnace.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod:block {
name = "Furnace",
tiles = {"furnace_top.png", "furnace_top.png", "furnace_front.png", "furnace_side.png"},
alt_tiles = {"", "", "furnace_front_on.png", ""},
is_rotatable = true,

on_block_placed = function(pos, world)
world:add_block_data(pos.x, pos.y, pos.z, 3, 1)
Expand Down
1 change: 1 addition & 0 deletions server/source/lua/LuaMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void LuaMod::registerBlock(const sol::table &table) {
block.setOnBlockActivated(onBlockActivated);
block.setOnTick(onTick);
block.setOnBlockPlaced(table["on_block_placed"]);
block.setRotatable(table["is_rotatable"].get_or(false));

sol::optional<sol::table> boundingBox = table["bounding_box"];
if (boundingBox != sol::nullopt) {
Expand Down
3 changes: 2 additions & 1 deletion server/source/network/ServerCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ void ServerCommandHandler::setupCallbacks() {
s32 x, y, z;
u32 block;
packet >> x >> y >> z >> block;
m_world.setBlock(x, y, z, block);
m_world.setBlock(x, y, z, block & 0xffff);
m_world.setData(x, y, z, block >> 16);

sf::Packet answer;
answer << Network::Command::BlockUpdate << x << y << z << block;
Expand Down
2 changes: 1 addition & 1 deletion server/source/world/ServerWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void ServerWorld::sendChunkData(const Client &client, ServerChunk *chunk) {
for (u16 z = 0 ; z < CHUNK_HEIGHT ; ++z) {
for (u16 y = 0 ; y < CHUNK_DEPTH ; ++y) {
for (u16 x = 0 ; x < CHUNK_WIDTH ; ++x) {
packet << u16(chunk->data()[z][y][x]);
packet << chunk->data()[z][y][x];
packet << chunk->lightmap().getLightData(x, y, z);

BlockData *blockData = chunk->getBlockData(x, y, z);
Expand Down

0 comments on commit ec7ef36

Please sign in to comment.