diff options
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r-- | src/localplayer.cpp | 214 |
1 files changed, 18 insertions, 196 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 2bd62dabf..df668b36d 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -52,24 +52,15 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, INodeDefManager *nodemgr = m_gamedef->ndef(); v3f position = getPosition(); - v3f oldpos = position; - v3s16 oldpos_i = floatToInt(oldpos, BS); v3f old_speed = m_speed; - /*std::cout<<"oldpos_i=("<<oldpos_i.X<<","<<oldpos_i.Y<<"," - <<oldpos_i.Z<<")"<<std::endl;*/ - - /* - Calculate new position - */ - position += m_speed * dtime; - // Skip collision detection if a special movement mode is used bool fly_allowed = m_gamedef->checkLocalPrivilege("fly"); bool free_move = fly_allowed && g_settings->getBool("free_move"); if(free_move) { + position += m_speed * dtime; setPosition(position); return; } @@ -78,9 +69,6 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, Collision detection */ - // Player position in nodes - v3s16 pos_i = floatToInt(position, BS); - /* Check if player is in water (the oscillating value) */ @@ -148,13 +136,6 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, f32 sneak_max = BS*0.4; /* - If sneaking, player has larger collision radius to keep from - falling - */ - /*if(control.sneak) - player_radius = sneak_max + d*1.1;*/ - - /* If sneaking, keep in range from the last walked node and don't fall off from it */ @@ -170,22 +151,8 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, { position.Y = min_y; - //v3f old_speed = m_speed; - if(m_speed.Y < 0) m_speed.Y = 0; - - /*if(collision_info) - { - // Report fall collision - if(old_speed.Y < m_speed.Y - 0.1) - { - CollisionInfo info; - info.t = COLLISION_FALL; - info.speed = m_speed.Y - old_speed.Y; - collision_info->push_back(info); - } - }*/ } } @@ -193,22 +160,22 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, Calculate player collision box (new and old) */ core::aabbox3d<f32> playerbox( - position.X - player_radius, - position.Y - 0.0, - position.Z - player_radius, - position.X + player_radius, - position.Y + player_height, - position.Z + player_radius - ); - core::aabbox3d<f32> playerbox_old( - oldpos.X - player_radius, - oldpos.Y - 0.0, - oldpos.Z - player_radius, - oldpos.X + player_radius, - oldpos.Y + player_height, - oldpos.Z + player_radius + -player_radius, + 0.0, + -player_radius, + player_radius, + player_height, + player_radius ); + float player_stepheight = touching_ground ? (BS*0.6) : (BS*0.2); + + v3f accel_f = v3f(0,0,0); + + collisionMoveResult result = collisionMoveSimple(&map, m_gamedef, + pos_max_d, playerbox, player_stepheight, dtime, + position, m_speed, accel_f); + /* If the player's feet touch the topside of any node, this is set to true. @@ -216,154 +183,9 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, Player is allowed to jump when this is true. */ bool touching_ground_was = touching_ground; - touching_ground = false; - - /*std::cout<<"Checking collisions for (" - <<oldpos_i.X<<","<<oldpos_i.Y<<","<<oldpos_i.Z - <<") -> (" - <<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z - <<"):"<<std::endl;*/ - - bool standing_on_unloaded = false; - - /* - Go through every node around the player - */ - for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++) - for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++) - for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++) - { - bool is_unloaded = false; - try{ - // Player collides into walkable nodes - if(nodemgr->get(map.getNode(v3s16(x,y,z))).walkable == false) - continue; - } - catch(InvalidPositionException &e) - { - is_unloaded = true; - // Doing nothing here will block the player from - // walking over map borders - } - - core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS); - - /* - See if the player is touching ground. - - Player touches ground if player's minimum Y is near node's - maximum Y and player's X-Z-area overlaps with the node's - X-Z-area. - - Use 0.15*BS so that it is easier to get on a node. - */ - if( - //fabs(nodebox.MaxEdge.Y-playerbox.MinEdge.Y) < d - fabs(nodebox.MaxEdge.Y-playerbox.MinEdge.Y) < 0.15*BS - && nodebox.MaxEdge.X-d > playerbox.MinEdge.X - && nodebox.MinEdge.X+d < playerbox.MaxEdge.X - && nodebox.MaxEdge.Z-d > playerbox.MinEdge.Z - && nodebox.MinEdge.Z+d < playerbox.MaxEdge.Z - ){ - touching_ground = true; - if(is_unloaded) - standing_on_unloaded = true; - } - - // If player doesn't intersect with node, ignore node. - if(playerbox.intersectsWithBox(nodebox) == false) - continue; - - /* - Go through every axis - */ - v3f dirs[3] = { - v3f(0,0,1), // back-front - v3f(0,1,0), // top-bottom - v3f(1,0,0), // right-left - }; - for(u16 i=0; i<3; i++) - { - /* - Calculate values along the axis - */ - f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]); - f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]); - f32 playermax = playerbox.MaxEdge.dotProduct(dirs[i]); - f32 playermin = playerbox.MinEdge.dotProduct(dirs[i]); - f32 playermax_old = playerbox_old.MaxEdge.dotProduct(dirs[i]); - f32 playermin_old = playerbox_old.MinEdge.dotProduct(dirs[i]); - - /* - Check collision for the axis. - Collision happens when player is going through a surface. - */ - /*f32 neg_d = d; - f32 pos_d = d; - // Make it easier to get on top of a node - if(i == 1) - neg_d = 0.15*BS; - bool negative_axis_collides = - (nodemax > playermin && nodemax <= playermin_old + neg_d - && m_speed.dotProduct(dirs[i]) < 0); - bool positive_axis_collides = - (nodemin < playermax && nodemin >= playermax_old - pos_d - && m_speed.dotProduct(dirs[i]) > 0);*/ - bool negative_axis_collides = - (nodemax > playermin && nodemax <= playermin_old + d - && m_speed.dotProduct(dirs[i]) < 0); - bool positive_axis_collides = - (nodemin < playermax && nodemin >= playermax_old - d - && m_speed.dotProduct(dirs[i]) > 0); - bool main_axis_collides = - negative_axis_collides || positive_axis_collides; - - /* - Check overlap of player and node in other axes - */ - bool other_axes_overlap = true; - for(u16 j=0; j<3; j++) - { - if(j == i) - continue; - f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]); - f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]); - f32 playermax = playerbox.MaxEdge.dotProduct(dirs[j]); - f32 playermin = playerbox.MinEdge.dotProduct(dirs[j]); - if(!(nodemax - d > playermin && nodemin + d < playermax)) - { - other_axes_overlap = false; - break; - } - } - - /* - If this is a collision, revert the position in the main - direction. - */ - if(other_axes_overlap && main_axis_collides) - { - //v3f old_speed = m_speed; - - m_speed -= m_speed.dotProduct(dirs[i]) * dirs[i]; - position -= position.dotProduct(dirs[i]) * dirs[i]; - position += oldpos.dotProduct(dirs[i]) * dirs[i]; - - /*if(collision_info) - { - // Report fall collision - if(old_speed.Y < m_speed.Y - 0.1) - { - CollisionInfo info; - info.t = COLLISION_FALL; - info.speed = m_speed.Y - old_speed.Y; - collision_info->push_back(info); - } - }*/ - } - - } - } // xyz + touching_ground = result.touching_ground; + + bool standing_on_unloaded = result.standing_on_unloaded; /* Check the nodes under the player to see from which node the |