-}
-
-void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
- core::list<CollisionInfo> *collision_info)
-{
- 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 free_move = g_settings->getBool("free_move");
- if(free_move)
- {
- setPosition(position);
- return;
- }
-
- /*
- Collision detection
- */
-
- // Player position in nodes
- v3s16 pos_i = floatToInt(position, BS);
-
- /*
- Check if player is in water (the oscillating value)
- */
- try{
- // If in water, the threshold of coming out is at higher y
- if(in_water)
- {
- v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
- in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
- }
- // If not in water, the threshold of going in is at lower y
- else
- {
- v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
- in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
- }
- }
- catch(InvalidPositionException &e)
- {
- in_water = false;
- }
-
- /*
- Check if player is in water (the stable value)
- */
- try{
- v3s16 pp = floatToInt(position + v3f(0,0,0), BS);
- in_water_stable = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
- }
- catch(InvalidPositionException &e)
- {
- in_water_stable = false;
- }
-
- /*
- Check if player is climbing
- */
-
- try {
- v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
- v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
- is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
- nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
- }
- catch(InvalidPositionException &e)
- {
- is_climbing = false;
- }
-
- /*
- Collision uncertainty radius
- Make it a bit larger than the maximum distance of movement
- */
- //f32 d = pos_max_d * 1.1;
- // A fairly large value in here makes moving smoother
- f32 d = 0.15*BS;
-
- // This should always apply, otherwise there are glitches
- assert(d > pos_max_d);
-
- float player_radius = BS*0.30;
- float player_height = BS*1.55;
-
- // Maximum distance over border for sneaking
- 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
- */
- if(control.sneak && m_sneak_node_exists)
- {
- f32 maxd = 0.5*BS + sneak_max;
- v3f lwn_f = intToFloat(m_sneak_node, BS);
- position.X = rangelim(position.X, lwn_f.X-maxd, lwn_f.X+maxd);
- position.Z = rangelim(position.Z, lwn_f.Z-maxd, lwn_f.Z+maxd);
-
- f32 min_y = lwn_f.Y + 0.5*BS;
- if(position.Y < min_y)
- {
- 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);
- }
- }*/
- }
- }
-
- /*
- 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
- );
-
- /*
- If the player's feet touch the topside of any node, this is
- set to true.
-
- 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
- }