+ // Seperate camera position for calculation
+ v3f my_cp = m_camera_position;
+
+ // Reposition the camera for third person view
+ if (m_camera_mode > CAMERA_MODE_FIRST)
+ {
+ if (m_camera_mode == CAMERA_MODE_THIRD_FRONT)
+ m_camera_direction *= -1;
+
+ my_cp.Y += 2;
+
+ // Calculate new position
+ bool abort = false;
+ for (int i = BS; i <= BS*2; i++)
+ {
+ my_cp.X = m_camera_position.X + m_camera_direction.X*-i;
+ my_cp.Z = m_camera_position.Z + m_camera_direction.Z*-i;
+ if (i > 12)
+ my_cp.Y = m_camera_position.Y + (m_camera_direction.Y*-i);
+
+ // Prevent camera positioned inside nodes
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+ MapNode n = c_env.getClientMap().getNodeNoEx(floatToInt(my_cp, BS));
+ const ContentFeatures& features = nodemgr->get(n);
+ if(features.walkable)
+ {
+ my_cp.X += m_camera_direction.X*-1*-BS/2;
+ my_cp.Z += m_camera_direction.Z*-1*-BS/2;
+ my_cp.Y += m_camera_direction.Y*-1*-BS/2;
+ abort = true;
+ break;
+ }
+ }
+
+ // If node blocks camera position don't move y to heigh
+ if (abort && my_cp.Y > player_position.Y+BS*2)
+ my_cp.Y = player_position.Y+BS*2;
+ }
+
+ // Update offset if too far away from the center of the map
+ m_camera_offset.X += CAMERA_OFFSET_STEP*
+ (((s16)(my_cp.X/BS) - m_camera_offset.X)/CAMERA_OFFSET_STEP);
+ m_camera_offset.Y += CAMERA_OFFSET_STEP*
+ (((s16)(my_cp.Y/BS) - m_camera_offset.Y)/CAMERA_OFFSET_STEP);
+ m_camera_offset.Z += CAMERA_OFFSET_STEP*
+ (((s16)(my_cp.Z/BS) - m_camera_offset.Z)/CAMERA_OFFSET_STEP);
+