@@ -11,9 +11,9 @@ namespace konstructs {
1111 static float CAMERA_OFFSET = 0 .5f ;
1212 static Vector3f CAMERA_OFFSET_VECTOR = Vector3f(0 , CAMERA_OFFSET, 0 );
1313
14- Player::Player (const int _id , const Vector3f _position , const float _rx ,
15- const float _ry ):
16- id (_id ), position(_position ), mrx(_rx ), mry(_ry ), flying(false ), dy(0 ) {}
14+ Player::Player (const int id , const Vector3f position , const float rx ,
15+ const float ry ):
16+ id (id ), position(position ), mrx(rx ), mry(ry ), flying(false ), dy(0 ) {}
1717
1818 Matrix4f Player::direction () const {
1919 return (Affine3f (AngleAxisf (mrx, Vector3f::UnitX ())) *
@@ -43,9 +43,30 @@ namespace konstructs {
4343 return vec;
4444 }
4545
46+ Vector3i Player::feet () const {
47+ return Vector3i (roundf (position[0 ]), roundf (position[1 ]) - 1 , roundf (position[2 ]));
48+ }
49+
50+ bool Player::can_place (Vector3i block, const World &world, const BlockData &blocks) {
51+ Vector3i f = feet ();
52+ /* Are we trying to place blocks on ourselves? */
53+ if (block (0 ) == f (0 ) && block (2 ) == f (2 ) && block (1 ) >= f (1 ) && block (1 ) < f (1 ) + 2 ) {
54+ /* We may place on our feet under certain circumstances */
55+ if (f (1 ) == block (1 )) {
56+ /* Allow placing on our feet if the block above our head is not an obstacle*/
57+ return !blocks.is_obstacle [world.get_block (Vector3i (f (0 ), f (1 ) + 2 , f (2 )))];
58+ } else {
59+ /* We are never allowed to place on our head */
60+ return false ;
61+ }
62+ }
63+ return true ;
64+ }
65+
4666 Vector3f Player::update_position (int sz, int sx, float dt,
4767 const World &world, const BlockData &blocks,
48- const float near_distance, const bool jump) {
68+ const float near_distance, const bool jump,
69+ const bool sneaking) {
4970 float vx = 0 , vy = 0 , vz = 0 ;
5071 if (!sz && !sx) { // Not mowing in X or Z
5172 vx = 0 ;
@@ -114,7 +135,7 @@ namespace konstructs {
114135 dy = std::max (dy, -250 .0f );
115136 }
116137 position += Vector3f (vx, vy + dy * ut, vz);
117- if (collide (world, blocks, near_distance)) {
138+ if (collide (world, blocks, near_distance, sneaking )) {
118139 dy = 0 ;
119140 }
120141 }
@@ -178,7 +199,8 @@ namespace konstructs {
178199 return mry;
179200 }
180201
181- int Player::collide (const World &world, const BlockData &blocks, const float near_distance) {
202+ int Player::collide (const World &world, const BlockData &blocks,
203+ const float near_distance, const bool sneaking) {
182204 int result = 0 ;
183205 float x = position[0 ];
184206 float y = position[1 ];
@@ -194,45 +216,54 @@ namespace konstructs {
194216 float py = y - ny;
195217 float pz = z - nz;
196218 float pad = near_distance * 2 ;
197- int r = 1 ;
198- for (int dp = -r; dp <= r; dp++) {
199- for (int dq = -r; dq <= r; dq++) {
200- for (int dk = -r; dk <= r; dk++) {
201- try {
202- ChunkData *chunk = world.chunk (Vector3i (p + dp, q + dq, k + dk)).get ();
203- if (blocks.is_obstacle [chunk->get (Vector3i (nx, ny-1 , nz))]) {
204- position[1 ] += 1 .0f ;
205- return 1 ;
206- }
207- for (int dy = 0 ; dy < height; dy++) {
208- if (px < -pad && blocks.is_obstacle [chunk->get (Vector3i (nx - 1 , ny - dy, nz))]) {
209- position[0 ] = nx - pad;
210- }
211- if (px > pad && blocks.is_obstacle [chunk->get (Vector3i (nx + 1 , ny - dy, nz))]) {
212- position[0 ] = nx + pad;
213- }
214- if (py < -pad && blocks.is_obstacle [chunk->get (Vector3i (nx, ny - dy - 1 , nz))]) {
215- position[1 ] = ny - pad;
216- result = 1 ;
217- }
218- if (py > (pad - CAMERA_OFFSET) && blocks.is_obstacle [chunk->get (Vector3i (nx, ny - dy + 1 , nz))]) {
219- position[1 ] = ny + pad - CAMERA_OFFSET;
220- result = 1 ;
221- }
222- if (pz < -pad && blocks.is_obstacle [chunk->get (Vector3i (nx, ny - dy, nz - 1 ))]) {
223- position[2 ] = nz - pad;
224- }
225- if (pz > pad && blocks.is_obstacle [chunk->get (Vector3i (nx, ny - dy, nz + 1 ))]) {
226- position[2 ] = nz + pad;
227- }
228- }
229- } catch (std::out_of_range e) {
230- continue ;
231- }
219+
220+ try {
221+
222+ if (blocks.is_obstacle [world.get_block (feet ())]) {
223+ position[1 ] += 1 .0f ;
224+ return 1 ;
225+ }
226+
227+ if (sneaking) {
228+ if (px < -pad && !blocks.is_obstacle [world.get_block (Vector3i (nx - 1 , ny - 2 , nz))]) {
229+ position[0 ] = nx - pad;
230+ }
231+ if (px > pad && !blocks.is_obstacle [world.get_block (Vector3i (nx + 1 , ny - 2 , nz))]) {
232+ position[0 ] = nx + pad;
233+ }
234+ if (pz < -pad && !blocks.is_obstacle [world.get_block (Vector3i (nx, ny - 2 , nz - 1 ))]) {
235+ position[2 ] = nz - pad;
236+ }
237+ if (pz > pad && !blocks.is_obstacle [world.get_block (Vector3i (nx, ny - 2 , nz + 1 ))]) {
238+ position[2 ] = nz + pad;
232239 }
233240 }
241+ for (int dy = 0 ; dy < height; dy++) {
242+ if (px < -pad && blocks.is_obstacle [world.get_block (Vector3i (nx - 1 , ny - dy, nz))]) {
243+ position[0 ] = nx - pad;
244+ }
245+ if (px > pad && blocks.is_obstacle [world.get_block (Vector3i (nx + 1 , ny - dy, nz))]) {
246+ position[0 ] = nx + pad;
247+ }
248+ if (py < -pad && blocks.is_obstacle [world.get_block (Vector3i (nx, ny - dy - 1 , nz))]) {
249+ position[1 ] = ny - pad;
250+ result = 1 ;
251+ }
252+ if (py > (pad - CAMERA_OFFSET) && blocks.is_obstacle [world.get_block (Vector3i (nx, ny - dy + 1 , nz))]) {
253+ position[1 ] = ny + pad - CAMERA_OFFSET;
254+ result = 1 ;
255+ }
256+ if (pz < -pad && blocks.is_obstacle [world.get_block (Vector3i (nx, ny - dy, nz - 1 ))]) {
257+ position[2 ] = nz - pad;
258+ }
259+ if (pz > pad && blocks.is_obstacle [world.get_block (Vector3i (nx, ny - dy, nz + 1 ))]) {
260+ position[2 ] = nz + pad;
261+ }
262+ }
263+ } catch (std::out_of_range e) {
264+ /* chunk was not loaded yet */
265+ return result;
234266 }
235-
236267 return result;
237268 }
238269};
0 commit comments