LCOV - code coverage report
Current view: top level - src - localplayer.cpp (source / functions) Hit Total Coverage
Test: report Lines: 155 260 59.6 %
Date: 2015-07-11 18:23:49 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "localplayer.h"
      21             : 
      22             : #include "event.h"
      23             : #include "collision.h"
      24             : #include "gamedef.h"
      25             : #include "nodedef.h"
      26             : #include "settings.h"
      27             : #include "environment.h"
      28             : #include "map.h"
      29             : #include "util/numeric.h"
      30             : 
      31             : /*
      32             :         LocalPlayer
      33             : */
      34             : 
      35           1 : LocalPlayer::LocalPlayer(IGameDef *gamedef, const char *name):
      36             :         Player(gamedef, name),
      37             :         parent(0),
      38             :         isAttached(false),
      39             :         overridePosition(v3f(0,0,0)),
      40             :         last_position(v3f(0,0,0)),
      41             :         last_speed(v3f(0,0,0)),
      42             :         last_pitch(0),
      43             :         last_yaw(0),
      44             :         last_keyPressed(0),
      45             :         last_animation(NO_ANIM),
      46             :         hotbar_image(""),
      47             :         hotbar_selected_image(""),
      48             :         light_color(255,255,255,255),
      49             :         m_sneak_node(32767,32767,32767),
      50             :         m_sneak_node_exists(false),
      51             :         m_old_node_below(32767,32767,32767),
      52             :         m_old_node_below_type("air"),
      53             :         m_need_to_get_new_sneak_node(true),
      54             :         m_can_jump(false),
      55           1 :         m_cao(NULL)
      56             : {
      57             :         // Initialize hp to 0, so that no hearts will be shown if server
      58             :         // doesn't support health points
      59           1 :         hp = 0;
      60           1 :         eye_offset_first = v3f(0,0,0);
      61           1 :         eye_offset_third = v3f(0,0,0);
      62           1 : }
      63             : 
      64           2 : LocalPlayer::~LocalPlayer()
      65             : {
      66           2 : }
      67             : 
      68        3748 : void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
      69             :                 std::vector<CollisionInfo> *collision_info)
      70             : {
      71        3748 :         Map *map = &env->getMap();
      72        3748 :         INodeDefManager *nodemgr = m_gamedef->ndef();
      73             : 
      74        3748 :         v3f position = getPosition();
      75             : 
      76             :         // Copy parent position if local player is attached
      77        3748 :         if(isAttached)
      78             :         {
      79           0 :                 setPosition(overridePosition);
      80           0 :                 m_sneak_node_exists = false;
      81           0 :                 return;
      82             :         }
      83             : 
      84             :         // Skip collision detection if noclip mode is used
      85        3748 :         bool fly_allowed = m_gamedef->checkLocalPrivilege("fly");
      86       18574 :         bool noclip = m_gamedef->checkLocalPrivilege("noclip") &&
      87       11078 :                 g_settings->getBool("noclip");
      88        3748 :         bool free_move = noclip && fly_allowed && g_settings->getBool("free_move");
      89        3748 :         if (free_move) {
      90           0 :                 position += m_speed * dtime;
      91           0 :                 setPosition(position);
      92           0 :                 m_sneak_node_exists = false;
      93           0 :                 return;
      94             :         }
      95             : 
      96             :         /*
      97             :                 Collision detection
      98             :         */
      99             : 
     100             :         bool is_valid_position;
     101        3748 :         MapNode node;
     102        3748 :         v3s16 pp;
     103             : 
     104             :         /*
     105             :                 Check if player is in liquid (the oscillating value)
     106             :         */
     107             : 
     108             :         // If in liquid, the threshold of coming out is at higher y
     109        3748 :         if (in_liquid)
     110             :         {
     111           0 :                 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
     112           0 :                 node = map->getNodeNoEx(pp, &is_valid_position);
     113           0 :                 if (is_valid_position) {
     114           0 :                         in_liquid = nodemgr->get(node.getContent()).isLiquid();
     115           0 :                         liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
     116             :                 } else {
     117           0 :                         in_liquid = false;
     118             :                 }
     119             :         }
     120             :         // If not in liquid, the threshold of going in is at lower y
     121             :         else
     122             :         {
     123        3748 :                 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
     124        3748 :                 node = map->getNodeNoEx(pp, &is_valid_position);
     125        3748 :                 if (is_valid_position) {
     126        3665 :                         in_liquid = nodemgr->get(node.getContent()).isLiquid();
     127        3665 :                         liquid_viscosity = nodemgr->get(node.getContent()).liquid_viscosity;
     128             :                 } else {
     129          83 :                         in_liquid = false;
     130             :                 }
     131             :         }
     132             : 
     133             : 
     134             :         /*
     135             :                 Check if player is in liquid (the stable value)
     136             :         */
     137        3748 :         pp = floatToInt(position + v3f(0,0,0), BS);
     138        3748 :         node = map->getNodeNoEx(pp, &is_valid_position);
     139        3748 :         if (is_valid_position) {
     140        3665 :                 in_liquid_stable = nodemgr->get(node.getContent()).isLiquid();
     141             :         } else {
     142          83 :                 in_liquid_stable = false;
     143             :         }
     144             : 
     145             :         /*
     146             :                 Check if player is climbing
     147             :         */
     148             : 
     149             : 
     150        3748 :         pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
     151        3748 :         v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
     152        3748 :         node = map->getNodeNoEx(pp, &is_valid_position);
     153             :         bool is_valid_position2;
     154        3748 :         MapNode node2 = map->getNodeNoEx(pp2, &is_valid_position2);
     155             : 
     156        3748 :         if (!(is_valid_position && is_valid_position2)) {
     157          83 :                 is_climbing = false;
     158             :         } else {
     159        3665 :                 is_climbing = (nodemgr->get(node.getContent()).climbable
     160        3665 :                                 || nodemgr->get(node2.getContent()).climbable) && !free_move;
     161             :         }
     162             : 
     163             : 
     164             :         /*
     165             :                 Collision uncertainty radius
     166             :                 Make it a bit larger than the maximum distance of movement
     167             :         */
     168             :         //f32 d = pos_max_d * 1.1;
     169             :         // A fairly large value in here makes moving smoother
     170        3748 :         f32 d = 0.15*BS;
     171             : 
     172             :         // This should always apply, otherwise there are glitches
     173        3748 :         sanity_check(d > pos_max_d);
     174             : 
     175             :         // Maximum distance over border for sneaking
     176        3748 :         f32 sneak_max = BS*0.4;
     177             : 
     178             :         /*
     179             :                 If sneaking, keep in range from the last walked node and don't
     180             :                 fall off from it
     181             :         */
     182       14992 :         if(control.sneak && m_sneak_node_exists &&
     183       11244 :                         !(fly_allowed && g_settings->getBool("free_move")) && !in_liquid &&
     184           0 :                         physics_override_sneak)
     185             :         {
     186           0 :                 f32 maxd = 0.5*BS + sneak_max;
     187           0 :                 v3f lwn_f = intToFloat(m_sneak_node, BS);
     188           0 :                 position.X = rangelim(position.X, lwn_f.X-maxd, lwn_f.X+maxd);
     189           0 :                 position.Z = rangelim(position.Z, lwn_f.Z-maxd, lwn_f.Z+maxd);
     190             : 
     191           0 :                 if(!is_climbing)
     192             :                 {
     193           0 :                         f32 min_y = lwn_f.Y + 0.5*BS;
     194           0 :                         if(position.Y < min_y)
     195             :                         {
     196           0 :                                 position.Y = min_y;
     197             : 
     198           0 :                                 if(m_speed.Y < 0)
     199           0 :                                         m_speed.Y = 0;
     200             :                         }
     201             :                 }
     202             :         }
     203             : 
     204             :         // this shouldn't be hardcoded but transmitted from server
     205        3748 :         float player_stepheight = touching_ground ? (BS*0.6) : (BS*0.2);
     206             : 
     207             : #ifdef __ANDROID__
     208             :         player_stepheight += (0.5 * BS);
     209             : #endif
     210             : 
     211        3748 :         v3f accel_f = v3f(0,0,0);
     212             : 
     213             :         collisionMoveResult result = collisionMoveSimple(env, m_gamedef,
     214             :                         pos_max_d, m_collisionbox, player_stepheight, dtime,
     215        7496 :                         position, m_speed, accel_f);
     216             : 
     217             :         /*
     218             :                 If the player's feet touch the topside of any node, this is
     219             :                 set to true.
     220             : 
     221             :                 Player is allowed to jump when this is true.
     222             :         */
     223        3748 :         bool touching_ground_was = touching_ground;
     224        3748 :         touching_ground = result.touching_ground;
     225             : 
     226             :     //bool standing_on_unloaded = result.standing_on_unloaded;
     227             : 
     228             :         /*
     229             :                 Check the nodes under the player to see from which node the
     230             :                 player is sneaking from, if any.  If the node from under
     231             :                 the player has been removed, the player falls.
     232             :         */
     233        3748 :         v3s16 current_node = floatToInt(position - v3f(0,BS/2,0), BS);
     234       18656 :         if(m_sneak_node_exists &&
     235       18572 :            nodemgr->get(map->getNodeNoEx(m_old_node_below)).name == "air" &&
     236           0 :            m_old_node_below_type != "air")
     237             :         {
     238             :                 // Old node appears to have been removed; that is,
     239             :                 // it wasn't air before but now it is
     240           0 :                 m_need_to_get_new_sneak_node = false;
     241           0 :                 m_sneak_node_exists = false;
     242             :         }
     243        3748 :         else if(nodemgr->get(map->getNodeNoEx(current_node)).name != "air")
     244             :         {
     245             :                 // We are on something, so make sure to recalculate the sneak
     246             :                 // node.
     247        3748 :                 m_need_to_get_new_sneak_node = true;
     248             :         }
     249        3748 :         if(m_need_to_get_new_sneak_node && physics_override_sneak)
     250             :         {
     251        3748 :                 v3s16 pos_i_bottom = floatToInt(position - v3f(0,BS/2,0), BS);
     252        3748 :                 v2f player_p2df(position.X, position.Z);
     253        3748 :                 f32 min_distance_f = 100000.0*BS;
     254             :                 // If already seeking from some node, compare to it.
     255             :                 /*if(m_sneak_node_exists)
     256             :                 {
     257             :                         v3f sneaknode_pf = intToFloat(m_sneak_node, BS);
     258             :                         v2f sneaknode_p2df(sneaknode_pf.X, sneaknode_pf.Z);
     259             :                         f32 d_horiz_f = player_p2df.getDistanceFrom(sneaknode_p2df);
     260             :                         f32 d_vert_f = fabs(sneaknode_pf.Y + BS*0.5 - position.Y);
     261             :                         // Ignore if player is not on the same level (likely dropped)
     262             :                         if(d_vert_f < 0.15*BS)
     263             :                                 min_distance_f = d_horiz_f;
     264             :                 }*/
     265        3748 :                 v3s16 new_sneak_node = m_sneak_node;
     266       14992 :                 for(s16 x=-1; x<=1; x++)
     267       44976 :                 for(s16 z=-1; z<=1; z++)
     268             :                 {
     269       33732 :                         v3s16 p = pos_i_bottom + v3s16(x,0,z);
     270       33732 :                         v3f pf = intToFloat(p, BS);
     271       33732 :                         v2f node_p2df(pf.X, pf.Z);
     272       33732 :                         f32 distance_f = player_p2df.getDistanceFrom(node_p2df);
     273       33732 :                         f32 max_axis_distance_f = MYMAX(
     274             :                                         fabs(player_p2df.X-node_p2df.X),
     275             :                                         fabs(player_p2df.Y-node_p2df.Y));
     276             : 
     277       49871 :                         if(distance_f > min_distance_f ||
     278       16139 :                                         max_axis_distance_f > 0.5*BS + sneak_max + 0.1*BS)
     279       47253 :                                 continue;
     280             : 
     281             : 
     282             :                         // The node to be sneaked on has to be walkable
     283       10479 :                         node = map->getNodeNoEx(p, &is_valid_position);
     284       10479 :                         if (!is_valid_position || nodemgr->get(node).walkable == false)
     285         747 :                                 continue;
     286             :                         // And the node above it has to be nonwalkable
     287        9732 :                         node = map->getNodeNoEx(p + v3s16(0,1,0), &is_valid_position);
     288        9732 :                         if (!is_valid_position || nodemgr->get(node).walkable) {
     289           0 :                                 continue;
     290             :                         }
     291        9732 :                         if (!physics_override_sneak_glitch) {
     292           0 :                                 node =map->getNodeNoEx(p + v3s16(0,2,0), &is_valid_position);
     293           0 :                                 if (!is_valid_position || nodemgr->get(node).walkable)
     294           0 :                                         continue;
     295             :                         }
     296             : 
     297        9732 :                         min_distance_f = distance_f;
     298        9732 :                         new_sneak_node = p;
     299             :                 }
     300             : 
     301        3748 :                 bool sneak_node_found = (min_distance_f < 100000.0*BS*0.9);
     302             : 
     303        3748 :                 m_sneak_node = new_sneak_node;
     304        3748 :                 m_sneak_node_exists = sneak_node_found;
     305             : 
     306             :                 /*
     307             :                         If sneaking, the player's collision box can be in air, so
     308             :                         this has to be set explicitly
     309             :                 */
     310        3748 :                 if(sneak_node_found && control.sneak)
     311           0 :                         touching_ground = true;
     312             :         }
     313             : 
     314             :         /*
     315             :                 Set new position
     316             :         */
     317        3748 :         setPosition(position);
     318             : 
     319             :         /*
     320             :                 Report collisions
     321             :         */
     322        3748 :         bool bouncy_jump = false;
     323             :         // Dont report if flying
     324        3748 :         if(collision_info && !(g_settings->getBool("free_move") && fly_allowed)) {
     325        6963 :                 for(size_t i=0; i<result.collisions.size(); i++) {
     326        3215 :                         const CollisionInfo &info = result.collisions[i];
     327        3215 :                         collision_info->push_back(info);
     328        6430 :                         if(info.new_speed.Y - info.old_speed.Y > 0.1*BS &&
     329        3215 :                                         info.bouncy)
     330           0 :                                 bouncy_jump = true;
     331             :                 }
     332             :         }
     333             : 
     334        3748 :         if(bouncy_jump && control.jump){
     335           0 :                 m_speed.Y += movement_speed_jump*BS;
     336           0 :                 touching_ground = false;
     337           0 :                 MtEvent *e = new SimpleTriggerEvent("PlayerJump");
     338           0 :                 m_gamedef->event()->put(e);
     339             :         }
     340             : 
     341        3748 :         if(!touching_ground_was && touching_ground){
     342           1 :                 MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
     343           1 :                 m_gamedef->event()->put(e);
     344             : 
     345             :                 // Set camera impact value to be used for view bobbing
     346           1 :                 camera_impact = getSpeed().Y * -1;
     347             :         }
     348             : 
     349             :         {
     350        3748 :                 camera_barely_in_ceiling = false;
     351        3748 :                 v3s16 camera_np = floatToInt(getEyePosition(), BS);
     352        3748 :                 MapNode n = map->getNodeNoEx(camera_np);
     353        3748 :                 if(n.getContent() != CONTENT_IGNORE){
     354        3665 :                         if(nodemgr->get(n).walkable && nodemgr->get(n).solidness == 2){
     355           0 :                                 camera_barely_in_ceiling = true;
     356             :                         }
     357             :                 }
     358             :         }
     359             : 
     360             :         /*
     361             :                 Update the node last under the player
     362             :         */
     363        3748 :         m_old_node_below = floatToInt(position - v3f(0,BS/2,0), BS);
     364        3748 :         m_old_node_below_type = nodemgr->get(map->getNodeNoEx(m_old_node_below)).name;
     365             : 
     366             :         /*
     367             :                 Check properties of the node on which the player is standing
     368             :         */
     369        3748 :         const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos()));
     370             :         // Determine if jumping is possible
     371        3748 :         m_can_jump = touching_ground && !in_liquid;
     372        3748 :         if(itemgroup_get(f.groups, "disable_jump"))
     373           0 :                 m_can_jump = false;
     374             : }
     375             : 
     376           0 : void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d)
     377             : {
     378           0 :         move(dtime, env, pos_max_d, NULL);
     379           0 : }
     380             : 
     381        1186 : void LocalPlayer::applyControl(float dtime)
     382             : {
     383             :         // Clear stuff
     384        1186 :         swimming_vertical = false;
     385             : 
     386        1186 :         setPitch(control.pitch);
     387        1186 :         setYaw(control.yaw);
     388             : 
     389             :         // Nullify speed and don't run positioning code if the player is attached
     390        1186 :         if(isAttached)
     391             :         {
     392           0 :                 setSpeed(v3f(0,0,0));
     393           0 :                 return;
     394             :         }
     395             : 
     396        1186 :         v3f move_direction = v3f(0,0,1);
     397        1186 :         move_direction.rotateXZBy(getYaw());
     398             : 
     399        1186 :         v3f speedH = v3f(0,0,0); // Horizontal (X, Z)
     400        1186 :         v3f speedV = v3f(0,0,0); // Vertical (Y)
     401             : 
     402        1186 :         bool fly_allowed = m_gamedef->checkLocalPrivilege("fly");
     403        1186 :         bool fast_allowed = m_gamedef->checkLocalPrivilege("fast");
     404             : 
     405        1186 :         bool free_move = fly_allowed && g_settings->getBool("free_move");
     406        1186 :         bool fast_move = fast_allowed && g_settings->getBool("fast_move");
     407             :         // When aux1_descends is enabled the fast key is used to go down, so fast isn't possible
     408        1186 :         bool fast_climb = fast_move && control.aux1 && !g_settings->getBool("aux1_descends");
     409        1186 :         bool continuous_forward = g_settings->getBool("continuous_forward");
     410        1186 :         bool always_fly_fast = g_settings->getBool("always_fly_fast");
     411             : 
     412             :         // Whether superspeed mode is used or not
     413        1186 :         bool superspeed = false;
     414             : 
     415        1186 :         if (always_fly_fast && free_move && fast_move)
     416           0 :                 superspeed = true;
     417             : 
     418             :         // Old descend control
     419        1186 :         if(g_settings->getBool("aux1_descends"))
     420             :         {
     421             :                 // If free movement and fast movement, always move fast
     422           0 :                 if(free_move && fast_move)
     423           0 :                         superspeed = true;
     424             : 
     425             :                 // Auxiliary button 1 (E)
     426           0 :                 if(control.aux1)
     427             :                 {
     428           0 :                         if(free_move)
     429             :                         {
     430             :                                 // In free movement mode, aux1 descends
     431           0 :                                 if(fast_move)
     432           0 :                                         speedV.Y = -movement_speed_fast;
     433             :                                 else
     434           0 :                                         speedV.Y = -movement_speed_walk;
     435             :                         }
     436           0 :                         else if(in_liquid || in_liquid_stable)
     437             :                         {
     438           0 :                                 speedV.Y = -movement_speed_walk;
     439           0 :                                 swimming_vertical = true;
     440             :                         }
     441           0 :                         else if(is_climbing)
     442             :                         {
     443           0 :                                 speedV.Y = -movement_speed_climb;
     444             :                         }
     445             :                         else
     446             :                         {
     447             :                                 // If not free movement but fast is allowed, aux1 is
     448             :                                 // "Turbo button"
     449           0 :                                 if(fast_move)
     450           0 :                                         superspeed = true;
     451             :                         }
     452             :                 }
     453             :         }
     454             :         // New minecraft-like descend control
     455             :         else
     456             :         {
     457             :                 // Auxiliary button 1 (E)
     458        1186 :                 if(control.aux1)
     459             :                 {
     460           0 :                         if(!is_climbing)
     461             :                         {
     462             :                                 // aux1 is "Turbo button"
     463           0 :                                 if(fast_move)
     464           0 :                                         superspeed = true;
     465             :                         }
     466             :                 }
     467             : 
     468        1186 :                 if(control.sneak)
     469             :                 {
     470           0 :                         if(free_move)
     471             :                         {
     472             :                                 // In free movement mode, sneak descends
     473           0 :                                 if (fast_move && (control.aux1 || always_fly_fast))
     474           0 :                                         speedV.Y = -movement_speed_fast;
     475             :                                 else
     476           0 :                                         speedV.Y = -movement_speed_walk;
     477             :                         }
     478           0 :                         else if(in_liquid || in_liquid_stable)
     479             :                         {
     480           0 :                                 if(fast_climb)
     481           0 :                                         speedV.Y = -movement_speed_fast;
     482             :                                 else
     483           0 :                                         speedV.Y = -movement_speed_walk;
     484           0 :                                 swimming_vertical = true;
     485             :                         }
     486           0 :                         else if(is_climbing)
     487             :                         {
     488           0 :                                 if(fast_climb)
     489           0 :                                         speedV.Y = -movement_speed_fast;
     490             :                                 else
     491           0 :                                         speedV.Y = -movement_speed_climb;
     492             :                         }
     493             :                 }
     494             :         }
     495             : 
     496        1186 :         if(continuous_forward)
     497           0 :                 speedH += move_direction;
     498             : 
     499        1186 :         if(control.up)
     500             :         {
     501         405 :                 if(continuous_forward)
     502           0 :                         superspeed = true;
     503             :                 else
     504         405 :                         speedH += move_direction;
     505             :         }
     506        1186 :         if(control.down)
     507             :         {
     508          37 :                 speedH -= move_direction;
     509             :         }
     510        1186 :         if(control.left)
     511             :         {
     512         148 :                 speedH += move_direction.crossProduct(v3f(0,1,0));
     513             :         }
     514        1186 :         if(control.right)
     515             :         {
     516         214 :                 speedH += move_direction.crossProduct(v3f(0,-1,0));
     517             :         }
     518        1186 :         if(control.jump)
     519             :         {
     520           0 :                 if (free_move) {
     521           0 :                         if (g_settings->getBool("aux1_descends") || always_fly_fast) {
     522           0 :                                 if (fast_move)
     523           0 :                                         speedV.Y = movement_speed_fast;
     524             :                                 else
     525           0 :                                         speedV.Y = movement_speed_walk;
     526             :                         } else {
     527           0 :                                 if(fast_move && control.aux1)
     528           0 :                                         speedV.Y = movement_speed_fast;
     529             :                                 else
     530           0 :                                         speedV.Y = movement_speed_walk;
     531             :                         }
     532             :                 }
     533           0 :                 else if(m_can_jump)
     534             :                 {
     535             :                         /*
     536             :                                 NOTE: The d value in move() affects jump height by
     537             :                                 raising the height at which the jump speed is kept
     538             :                                 at its starting value
     539             :                         */
     540           0 :                         v3f speedJ = getSpeed();
     541           0 :                         if(speedJ.Y >= -0.5 * BS)
     542             :                         {
     543           0 :                                 speedJ.Y = movement_speed_jump * physics_override_jump;
     544           0 :                                 setSpeed(speedJ);
     545             : 
     546           0 :                                 MtEvent *e = new SimpleTriggerEvent("PlayerJump");
     547           0 :                                 m_gamedef->event()->put(e);
     548             :                         }
     549             :                 }
     550           0 :                 else if(in_liquid)
     551             :                 {
     552           0 :                         if(fast_climb)
     553           0 :                                 speedV.Y = movement_speed_fast;
     554             :                         else
     555           0 :                                 speedV.Y = movement_speed_walk;
     556           0 :                         swimming_vertical = true;
     557             :                 }
     558           0 :                 else if(is_climbing)
     559             :                 {
     560           0 :                         if(fast_climb)
     561           0 :                                 speedV.Y = movement_speed_fast;
     562             :                         else
     563           0 :                                 speedV.Y = movement_speed_climb;
     564             :                 }
     565             :         }
     566             : 
     567             :         // The speed of the player (Y is ignored)
     568        1186 :         if(superspeed || (is_climbing && fast_climb) || ((in_liquid || in_liquid_stable) && fast_climb))
     569           0 :                 speedH = speedH.normalize() * movement_speed_fast;
     570        1186 :         else if(control.sneak && !free_move && !in_liquid && !in_liquid_stable)
     571           0 :                 speedH = speedH.normalize() * movement_speed_crouch;
     572             :         else
     573        1186 :                 speedH = speedH.normalize() * movement_speed_walk;
     574             : 
     575             :         // Acceleration increase
     576        1186 :         f32 incH = 0; // Horizontal (X, Z)
     577        1186 :         f32 incV = 0; // Vertical (Y)
     578        1186 :         if((!touching_ground && !free_move && !is_climbing && !in_liquid) || (!free_move && m_can_jump && control.jump))
     579             :         {
     580             :                 // Jumping and falling
     581           2 :                 if(superspeed || (fast_move && control.aux1))
     582           0 :                         incH = movement_acceleration_fast * BS * dtime;
     583             :                 else
     584           2 :                         incH = movement_acceleration_air * BS * dtime;
     585           2 :                 incV = 0; // No vertical acceleration in air
     586             :         }
     587        1184 :         else if (superspeed || (is_climbing && fast_climb) || ((in_liquid || in_liquid_stable) && fast_climb))
     588           0 :                 incH = incV = movement_acceleration_fast * BS * dtime;
     589             :         else
     590        1184 :                 incH = incV = movement_acceleration_default * BS * dtime;
     591             : 
     592             :         // Accelerate to target speed with maximum increment
     593        1186 :         accelerateHorizontal(speedH * physics_override_speed, incH * physics_override_speed);
     594        1186 :         accelerateVertical(speedV * physics_override_speed, incV * physics_override_speed);
     595             : }
     596             : 
     597        4914 : v3s16 LocalPlayer::getStandingNodePos()
     598             : {
     599        4914 :         if(m_sneak_node_exists)
     600        4831 :                 return m_sneak_node;
     601          83 :         return floatToInt(getPosition() - v3f(0, BS, 0), BS);
     602           3 : }
     603             : 

Generated by: LCOV version 1.11