Allow the player to dig the node the camera is into
That allows them to escape from being unable to move due to being trapped with the camera inside a node (assuming the node is diggable). Note: The implementation is a bit of a hack. It doesn't consider the lookAt direction.
This commit is contained in:
parent
e5b5ba9568
commit
ae9b47e018
@ -250,19 +250,49 @@ void BlockCursor::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::ivec4 BlockCursor::findSelectedBlock() const {
|
glm::ivec4 BlockCursor::findSelectedBlock() const {
|
||||||
glm::dvec3 lookAt{m_player.pointTargetedX() - m_player.camera().getPosition().x,
|
|
||||||
m_player.pointTargetedY() - m_player.camera().getPosition().y,
|
|
||||||
m_player.pointTargetedZ() - m_player.camera().getPosition().z};
|
|
||||||
|
|
||||||
glm::dvec3 position{m_player.camera().getPosition().x,
|
glm::dvec3 position{m_player.camera().getPosition().x,
|
||||||
m_player.camera().getPosition().y,
|
m_player.camera().getPosition().y,
|
||||||
m_player.camera().getPosition().z};
|
m_player.camera().getPosition().z};
|
||||||
|
|
||||||
|
int_fast32_t bestX = int_fast32_t(floor(position.x));
|
||||||
|
int_fast32_t bestY = int_fast32_t(floor(position.y));
|
||||||
|
int_fast32_t bestZ = int_fast32_t(floor(position.z));
|
||||||
|
|
||||||
|
// Deal with a degenerate case: camera in the middle of a block
|
||||||
|
uint_fast32_t blockID = m_world.getBlock(bestX, bestY, bestZ);
|
||||||
|
const Block &block = Registry::getInstance().getBlock(blockID);
|
||||||
|
if(blockID && block.drawType() != BlockDrawType::Liquid) {
|
||||||
|
// We're inside a node, therefore there's no face, but we still need
|
||||||
|
// to return a valid block. We use face 6 for that. For rightclicks,
|
||||||
|
// it should attempt to place the block on the same node clicked, and
|
||||||
|
// fail because it's already occupied. For digs, it should just dig
|
||||||
|
// the node.
|
||||||
|
return glm::ivec4{bestX, bestY, bestZ, 6};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still the degenerate case, but this time for the sub-case where
|
||||||
|
// the coordinates of the player are exact integers, thus lying exactly
|
||||||
|
// between two faces (or four, if it's in a corner). In this situation,
|
||||||
|
// the raycasting algorithm allows us to get rid of all blocks except for
|
||||||
|
// the one in the northwest corner. Deal with that case here.
|
||||||
|
// NOTE: We don't deal with height because it's unlikely that the
|
||||||
|
// camera ends up being at an integer position.
|
||||||
|
if(double(bestX) == position.x && double(bestZ) == position.z) {
|
||||||
|
blockID = m_world.getBlock(bestX - 1, bestY, bestZ - 1);
|
||||||
|
const Block &block = Registry::getInstance().getBlock(blockID);
|
||||||
|
if(blockID && block.drawType() != BlockDrawType::Liquid) {
|
||||||
|
return glm::ivec4{bestX - 1, bestY, bestZ - 1, 6};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::dvec3 lookAt{m_player.pointTargetedX() - m_player.camera().getPosition().x,
|
||||||
|
m_player.pointTargetedY() - m_player.camera().getPosition().y,
|
||||||
|
m_player.pointTargetedZ() - m_player.camera().getPosition().z};
|
||||||
|
|
||||||
// Ray casting algorithm to find out which block we are looking at
|
// Ray casting algorithm to find out which block we are looking at
|
||||||
const double maxReach = 10.;
|
const double maxReach = 10.;
|
||||||
double bestDepth;
|
double bestDepth;
|
||||||
int_fast8_t bestFace = -1;
|
int_fast8_t bestFace = -1;
|
||||||
int_fast32_t bestX = 0, bestY = 0, bestZ = 0;
|
|
||||||
|
|
||||||
glm::dvec3 lookAtN = glm::normalize(lookAt);
|
glm::dvec3 lookAtN = glm::normalize(lookAt);
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ void BlockCursorRaycast::rayCastToAxis(const Axis axis, const glm::dvec3 &positi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int_fast32_t firstNodeRow = int_fast32_t(floor(posCoord));
|
int_fast32_t firstNodeRow = lookAtCoord < 0. ? int_fast32_t(floor(posCoord)) : int_fast32_t(ceil(posCoord)) - 1;
|
||||||
int_fast32_t lastNodeRow = int_fast32_t(floor(posCoord + lookAtCoord * maxReach));
|
int_fast32_t lastNodeRow = int_fast32_t(floor(posCoord + lookAtCoord * maxReach));
|
||||||
|
|
||||||
int_fast8_t dir = (lookAtCoord > 0.) - (lookAtCoord < 0.);
|
int_fast8_t dir = (lookAtCoord > 0.) - (lookAtCoord < 0.);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user