- 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
- */
- if(is_frozen) {
- // Still move very slowly so as not to feel all completely stuck
- position += m_speed * dtime * 0.001;
- }
- else {
- position += m_speed * dtime;
- }
-
- /*
- If the player enters an unloaded chunk this is set to true.
- */
- is_frozen = false;
-
- // 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 = content_liquid(map.getNode(pp).getContent());
- }
- // 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 = content_liquid(map.getNode(pp).getContent());
- }
- }
- 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 = content_liquid(map.getNode(pp).getContent());
- }
- 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 = ((content_features(map.getNode(pp).getContent()).climbable ||
- content_features(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.35;
- float player_height = BS*1.7;
-
- // 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);
- }
- }*/
- }