Skip to content

Commit

Permalink
Merge pull request #182 from konstructs/fix-head-inside-blocks-bug
Browse files Browse the repository at this point in the history
Fix head inside blocks bug
  • Loading branch information
petterarvidsson committed Jun 9, 2016
2 parents 975f062 + 58e5437 commit fa0bf3d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 48 deletions.
9 changes: 7 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define KONSTRUCTS_KEY_RIGHT 'D'
#define KONSTRUCTS_KEY_JUMP GLFW_KEY_SPACE
#define KONSTRUCTS_KEY_FLY GLFW_KEY_TAB
#define KONSTRUCTS_KEY_SNEAK GLFW_KEY_LEFT_SHIFT
#define KONSTRUCTS_KEY_INVENTORY 'E'
using std::cout;
using std::cerr;
Expand Down Expand Up @@ -134,7 +135,7 @@ class Konstructs: public nanogui::Screen {
auto &l = *looking_at;
if(button == GLFW_MOUSE_BUTTON_1 && down) {
client.click_at(1, l.second.position, translate_button(button), hud.get_selection());
} else if(button == GLFW_MOUSE_BUTTON_2 && down) {
} else if(button == GLFW_MOUSE_BUTTON_2 && down && player.can_place(l.first.position, world, blocks)) {
optional<ItemStack> selected = hud.selected();
if(selected) {
std::shared_ptr<ChunkData> updated_chunk =
Expand Down Expand Up @@ -273,6 +274,7 @@ class Konstructs: public nanogui::Screen {
int sx = 0;
int sz = 0;
bool jump = false;
bool sneak = false;
double now = glfwGetTime();
double dt = now - last_frame;
dt = MIN(dt, 0.2);
Expand All @@ -294,8 +296,11 @@ class Konstructs: public nanogui::Screen {
if(glfwGetKey(mGLFWWindow, KONSTRUCTS_KEY_JUMP)) {
jump = true;
}
if(glfwGetKey(mGLFWWindow, KONSTRUCTS_KEY_SNEAK)) {
sneak = true;
}
client.position(player.update_position(sz, sx, (float)dt, world,
blocks, near_distance, jump),
blocks, near_distance, jump, sneak),
player.rx(), player.ry());
}

Expand Down
115 changes: 73 additions & 42 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace konstructs {
static float CAMERA_OFFSET = 0.5f;
static Vector3f CAMERA_OFFSET_VECTOR = Vector3f(0, CAMERA_OFFSET, 0);

Player::Player(const int _id, const Vector3f _position, const float _rx,
const float _ry):
id(_id), position(_position), mrx(_rx), mry(_ry), flying(false), dy(0) {}
Player::Player(const int id, const Vector3f position, const float rx,
const float ry):
id(id), position(position), mrx(rx), mry(ry), flying(false), dy(0) {}

Matrix4f Player::direction() const {
return (Affine3f(AngleAxisf(mrx, Vector3f::UnitX())) *
Expand Down Expand Up @@ -43,9 +43,30 @@ namespace konstructs {
return vec;
}

Vector3i Player::feet() const {
return Vector3i(roundf(position[0]), roundf(position[1]) - 1, roundf(position[2]));
}

bool Player::can_place(Vector3i block, const World &world, const BlockData &blocks) {
Vector3i f = feet();
/* Are we trying to place blocks on ourselves? */
if(block(0) == f(0) && block(2) == f(2) && block(1) >= f(1) && block(1) < f(1) + 2) {
/* We may place on our feet under certain circumstances */
if(f(1) == block(1)) {
/* Allow placing on our feet if the block above our head is not an obstacle*/
return !blocks.is_obstacle[world.get_block(Vector3i(f(0), f(1) + 2, f(2)))];
} else {
/* We are never allowed to place on our head */
return false;
}
}
return true;
}

Vector3f Player::update_position(int sz, int sx, float dt,
const World &world, const BlockData &blocks,
const float near_distance, const bool jump) {
const float near_distance, const bool jump,
const bool sneaking) {
float vx = 0, vy = 0, vz = 0;
if (!sz && !sx) { // Not mowing in X or Z
vx = 0;
Expand Down Expand Up @@ -114,7 +135,7 @@ namespace konstructs {
dy = std::max(dy, -250.0f);
}
position += Vector3f(vx, vy + dy * ut, vz);
if (collide(world, blocks, near_distance)) {
if (collide(world, blocks, near_distance, sneaking)) {
dy = 0;
}
}
Expand Down Expand Up @@ -178,7 +199,8 @@ namespace konstructs {
return mry;
}

int Player::collide(const World &world, const BlockData &blocks, const float near_distance) {
int Player::collide(const World &world, const BlockData &blocks,
const float near_distance, const bool sneaking) {
int result = 0;
float x = position[0];
float y = position[1];
Expand All @@ -194,45 +216,54 @@ namespace konstructs {
float py = y - ny;
float pz = z - nz;
float pad = near_distance * 2;
int r = 1;
for (int dp = -r; dp <= r; dp++) {
for (int dq = -r; dq <= r; dq++) {
for (int dk = -r; dk <= r; dk++) {
try {
ChunkData *chunk = world.chunk(Vector3i(p + dp, q + dq, k + dk)).get();
if (blocks.is_obstacle[chunk->get(Vector3i(nx, ny-1, nz))]) {
position[1] += 1.0f;
return 1;
}
for (int dy = 0; dy < height; dy++) {
if (px < -pad && blocks.is_obstacle[chunk->get(Vector3i(nx - 1, ny - dy, nz))]) {
position[0] = nx - pad;
}
if (px > pad && blocks.is_obstacle[chunk->get(Vector3i(nx + 1, ny - dy, nz))]) {
position[0] = nx + pad;
}
if (py < -pad && blocks.is_obstacle[chunk->get(Vector3i(nx, ny - dy - 1, nz))]) {
position[1] = ny - pad;
result = 1;
}
if (py > (pad - CAMERA_OFFSET) && blocks.is_obstacle[chunk->get(Vector3i(nx, ny - dy + 1, nz))]) {
position[1] = ny + pad - CAMERA_OFFSET;
result = 1;
}
if (pz < -pad && blocks.is_obstacle[chunk->get(Vector3i(nx, ny - dy, nz - 1))]) {
position[2] = nz - pad;
}
if (pz > pad && blocks.is_obstacle[chunk->get(Vector3i(nx, ny - dy, nz + 1))]) {
position[2] = nz + pad;
}
}
} catch(std::out_of_range e) {
continue;
}

try {

if (blocks.is_obstacle[world.get_block(feet())]) {
position[1] += 1.0f;
return 1;
}

if(sneaking) {
if (px < -pad && !blocks.is_obstacle[world.get_block(Vector3i(nx - 1, ny - 2, nz))]) {
position[0] = nx - pad;
}
if (px > pad && !blocks.is_obstacle[world.get_block(Vector3i(nx + 1, ny - 2, nz))]) {
position[0] = nx + pad;
}
if (pz < -pad && !blocks.is_obstacle[world.get_block(Vector3i(nx, ny - 2, nz - 1))]) {
position[2] = nz - pad;
}
if (pz > pad && !blocks.is_obstacle[world.get_block(Vector3i(nx, ny - 2, nz + 1))]) {
position[2] = nz + pad;
}
}
for (int dy = 0; dy < height; dy++) {
if (px < -pad && blocks.is_obstacle[world.get_block(Vector3i(nx - 1, ny - dy, nz))]) {
position[0] = nx - pad;
}
if (px > pad && blocks.is_obstacle[world.get_block(Vector3i(nx + 1, ny - dy, nz))]) {
position[0] = nx + pad;
}
if (py < -pad && blocks.is_obstacle[world.get_block(Vector3i(nx, ny - dy - 1, nz))]) {
position[1] = ny - pad;
result = 1;
}
if (py > (pad - CAMERA_OFFSET) && blocks.is_obstacle[world.get_block(Vector3i(nx, ny - dy + 1, nz))]) {
position[1] = ny + pad - CAMERA_OFFSET;
result = 1;
}
if (pz < -pad && blocks.is_obstacle[world.get_block(Vector3i(nx, ny - dy, nz - 1))]) {
position[2] = nz - pad;
}
if (pz > pad && blocks.is_obstacle[world.get_block(Vector3i(nx, ny - dy, nz + 1))]) {
position[2] = nz + pad;
}
}
} catch(std::out_of_range e) {
/* chunk was not loaded yet */
return result;
}

return result;
}
};
11 changes: 7 additions & 4 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ namespace konstructs {

class Player {
public:
Player(const int _id, const Vector3f _position,
const float _rx, const float _ry);
Player(const int id, const Vector3f position,
const float rx, const float ry);
Matrix4f direction() const;
Matrix4f translation() const;
Matrix4f view() const;
Vector3f camera() const;
Vector3f camera_direction() const;
Vector3i feet() const;
bool can_place(Vector3i block, const World &world, const BlockData &blocks);
Vector3f update_position(int sz, int sx, float dt,
const World &world, const BlockData &blocks,
const float near_distance, const bool jump);
const float near_distance, const bool jump, const bool sneaking);
optional<pair<Block, Block>> looking_at(const World &world,
const BlockData &blocks) const;
void rotate_x(float speed);
Expand All @@ -34,7 +36,8 @@ namespace konstructs {
float ry();
Vector3f position;
private:
int collide(const World &world, const BlockData &blocks, const float near_distance);
int collide(const World &world, const BlockData &blocks,
const float near_distance, const bool sneaking);
float mrx;
float mry;
bool flying;
Expand Down
4 changes: 4 additions & 0 deletions src/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ namespace konstructs {
requested.erase(pos);
}

const char World::get_block(const Vector3i &block_pos) const {
return chunks.at(chunked_vec_int(block_pos))->get(block_pos);
}

const std::shared_ptr<ChunkData> World::chunk_at(const Vector3i &block_pos) const {
return chunks.at(chunked_vec_int(block_pos));
}
Expand Down
1 change: 1 addition & 0 deletions src/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace konstructs {
bool chunk_updated_since_requested(const Vector3i &pos) const;
void delete_unused_chunks(const Vector3f position, const int radi);
void insert(std::shared_ptr<ChunkData> data);
const char get_block(const Vector3i &block_pos) const;
const std::shared_ptr<ChunkData> chunk_at(const Vector3i &block_pos) const;
const std::shared_ptr<ChunkData> chunk(const Vector3i &chunk_pos) const;
const std::vector<std::shared_ptr<ChunkData>> atAndAround(const Vector3i &pos) const;
Expand Down

0 comments on commit fa0bf3d

Please sign in to comment.