X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fplayer.cpp;h=1e064c1dac557d43c92ab9663c9d552f4c3f8e7b;hb=eabf05758e3ba5f6f4bb1b8d1d1f02179b84e410;hp=068b51790117aea0bca74c699dd4710dd030dcdd;hpb=88cdd3a363668cfb2fd07b5381cce29738aed0bf;p=dragonfireclient.git diff --git a/src/player.cpp b/src/player.cpp index 068b51790..1e064c1da 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1,763 +1,236 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "player.h" -#include "map.h" -#include "connection.h" + +#include +#include "threading/mutex_auto_lock.h" +#include "util/numeric.h" +#include "hud.h" #include "constants.h" -#include "utility.h" -#ifndef SERVER -#include -#endif -#include "main.h" // For g_settings -#include "settings.h" -#include "nodedef.h" -#include "collision.h" -#include "environment.h" #include "gamedef.h" +#include "settings.h" +#include "log.h" +#include "porting.h" // strlcpy -Player::Player(IGameDef *gamedef): - touching_ground(false), - in_water(false), - in_water_stable(false), - is_climbing(false), - swimming_up(false), - inventory(gamedef->idef()), - inventory_backup(NULL), - hp(20), - peer_id(PEER_ID_INEXISTENT), -// protected - m_gamedef(gamedef), - m_pitch(0), - m_yaw(0), - m_speed(0,0,0), - m_position(0,0,0) -{ - updateName(""); - resetInventory(); -} -Player::~Player() +Player::Player(const char *name, IItemDefManager *idef): + inventory(idef) { - delete inventory_backup; -} + strlcpy(m_name, name, PLAYERNAME_SIZE); -void Player::resetInventory() -{ inventory.clear(); inventory.addList("main", PLAYER_INVENTORY_SIZE); - inventory.addList("craft", 9); + InventoryList *craft = inventory.addList("craft", 9); + craft->setWidth(3); inventory.addList("craftpreview", 1); inventory.addList("craftresult", 1); + inventory.setModified(false); + + // Can be redefined via Lua + inventory_formspec = "size[8,7.5]" + //"image[1,0.6;1,2;player.png]" + "list[current_player;main;0,3.5;8,4;]" + "list[current_player;craft;3,0;3,3;]" + "listring[]" + "list[current_player;craftpreview;7,1;1,1;]"; + + // Initialize movement settings at default values, so movement can work + // if the server fails to send them + movement_acceleration_default = 3 * BS; + movement_acceleration_air = 2 * BS; + movement_acceleration_fast = 10 * BS; + movement_speed_walk = 4 * BS; + movement_speed_crouch = 1.35 * BS; + movement_speed_fast = 20 * BS; + movement_speed_climb = 2 * BS; + movement_speed_jump = 6.5 * BS; + movement_liquid_fluidity = 1 * BS; + movement_liquid_fluidity_smooth = 0.5 * BS; + movement_liquid_sink = 10 * BS; + movement_gravity = 9.81 * BS; + local_animation_speed = 0.0; + + hud_flags = + HUD_FLAG_HOTBAR_VISIBLE | HUD_FLAG_HEALTHBAR_VISIBLE | + HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE | + HUD_FLAG_BREATHBAR_VISIBLE | HUD_FLAG_MINIMAP_VISIBLE | + HUD_FLAG_MINIMAP_RADAR_VISIBLE | HUD_FLAG_BASIC_DEBUG; + + hud_hotbar_itemcount = HUD_HOTBAR_ITEMCOUNT_DEFAULT; + + m_player_settings.readGlobalSettings(); + // Register player setting callbacks + for (const std::string &name : m_player_settings.setting_names) + g_settings->registerChangedCallback(name, + &Player::settingsChangedCallback, &m_player_settings); } -// Y direction is ignored -void Player::accelerate(v3f target_speed, f32 max_increase) +Player::~Player() { - v3f d_wanted = target_speed - m_speed; - d_wanted.Y = 0; - f32 dl_wanted = d_wanted.getLength(); - f32 dl = dl_wanted; - if(dl > max_increase) - dl = max_increase; - - v3f d = d_wanted.normalize() * dl; - - m_speed.X += d.X; - m_speed.Z += d.Z; - //m_speed += d; - -#if 0 // old code - if(m_speed.X < target_speed.X - max_increase) - m_speed.X += max_increase; - else if(m_speed.X > target_speed.X + max_increase) - m_speed.X -= max_increase; - else if(m_speed.X < target_speed.X) - m_speed.X = target_speed.X; - else if(m_speed.X > target_speed.X) - m_speed.X = target_speed.X; - - if(m_speed.Z < target_speed.Z - max_increase) - m_speed.Z += max_increase; - else if(m_speed.Z > target_speed.Z + max_increase) - m_speed.Z -= max_increase; - else if(m_speed.Z < target_speed.Z) - m_speed.Z = target_speed.Z; - else if(m_speed.Z > target_speed.Z) - m_speed.Z = target_speed.Z; -#endif + // m_player_settings becomes invalid, remove callbacks + for (const std::string &name : m_player_settings.setting_names) + g_settings->deregisterChangedCallback(name, + &Player::settingsChangedCallback, &m_player_settings); + clearHud(); } -v3s16 Player::getLightPosition() const +void Player::setWieldIndex(u16 index) { - return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); + const InventoryList *mlist = inventory.getList("main"); + m_wield_index = MYMIN(index, mlist ? mlist->getSize() : 0); } -void Player::serialize(std::ostream &os) +ItemStack &Player::getWieldedItem(ItemStack *selected, ItemStack *hand) const { - // Utilize a Settings object for storing values - Settings args; - args.setS32("version", 1); - args.set("name", m_name); - //args.set("password", m_password); - args.setFloat("pitch", m_pitch); - args.setFloat("yaw", m_yaw); - args.setV3F("position", m_position); - args.setS32("hp", hp); - - args.writeLines(os); - - os<<"PlayerArgsEnd\n"; - - // If actual inventory is backed up due to creative mode, save it - // instead of the dummy creative mode inventory - if(inventory_backup) - inventory_backup->serialize(os); - else - inventory.serialize(os); -} + assert(selected); -void Player::deSerialize(std::istream &is) -{ - Settings args; - - for(;;) - { - if(is.eof()) - throw SerializationError - ("Player::deSerialize(): PlayerArgsEnd not found"); - std::string line; - std::getline(is, line); - std::string trimmedline = trim(line); - if(trimmedline == "PlayerArgsEnd") - break; - args.parseConfigLine(line); - } + const InventoryList *mlist = inventory.getList("main"); // TODO: Make this generic + const InventoryList *hlist = inventory.getList("hand"); - //args.getS32("version"); // Version field value not used - std::string name = args.get("name"); - updateName(name.c_str()); - setPitch(args.getFloat("pitch")); - setYaw(args.getFloat("yaw")); - setPosition(args.getV3F("position")); - try{ - hp = args.getS32("hp"); - }catch(SettingNotFoundException &e){ - hp = 20; - } + if (mlist && m_wield_index < mlist->getSize()) + *selected = mlist->getItem(m_wield_index); - inventory.deSerialize(is); + if (hand && hlist) + *hand = hlist->getItem(0); - if(inventory.getList("craftpreview") == NULL) - { - // Convert players without craftpreview - inventory.addList("craftpreview", 1); - - bool craftresult_is_preview = true; - if(args.exists("craftresult_is_preview")) - craftresult_is_preview = args.getBool("craftresult_is_preview"); - if(craftresult_is_preview) - { - // Clear craftresult - inventory.getList("craftresult")->changeItem(0, ItemStack()); - } - } + // Return effective tool item + return (hand && selected->name.empty()) ? *hand : *selected; } -#ifndef SERVER -/* - LocalPlayer -*/ - -LocalPlayer::LocalPlayer(IGameDef *gamedef): - Player(gamedef), - m_sneak_node(32767,32767,32767), - m_sneak_node_exists(false) +u32 Player::addHud(HudElement *toadd) { - // Initialize hp to 0, so that no hearts will be shown if server - // doesn't support health points - hp = 0; -} + MutexAutoLock lock(m_mutex); -LocalPlayer::~LocalPlayer() -{ + u32 id = getFreeHudID(); + + if (id < hud.size()) + hud[id] = toadd; + else + hud.push_back(toadd); + + return id; } -void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, - core::list *collision_info) +HudElement* Player::getHud(u32 id) { - INodeDefManager *nodemgr = m_gamedef->ndef(); + MutexAutoLock lock(m_mutex); - v3f position = getPosition(); - v3f oldpos = position; - v3s16 oldpos_i = floatToInt(oldpos, BS); + if (id < hud.size()) + return hud[id]; - v3f old_speed = m_speed; + return NULL; +} - /*std::cout<<"oldpos_i=("<getBool("free_move"); - if(free_move) - { - setPosition(position); - return; + HudElement* retval = NULL; + if (id < hud.size()) { + retval = hud[id]; + hud[id] = NULL; } + return retval; +} - /* - 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; - } +void Player::clearHud() +{ + MutexAutoLock lock(m_mutex); - /* - 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; + while(!hud.empty()) { + delete hud.back(); + hud.pop_back(); } +} - /* - Check if player is climbing - */ +#ifndef SERVER - 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; - } +u32 PlayerControl::getKeysPressed() const +{ + u32 keypress_bits = + ( (u32)(jump & 1) << 4) | + ( (u32)(aux1 & 1) << 5) | + ( (u32)(sneak & 1) << 6) | + ( (u32)(dig & 1) << 7) | + ( (u32)(place & 1) << 8) | + ( (u32)(zoom & 1) << 9) + ; + + // If any direction keys are pressed pass those through + if (direction_keys != 0) + { + keypress_bits |= direction_keys; + } + // Otherwise set direction keys based on joystick movement (for mod compatibility) + else if (isMoving()) + { + float abs_d; + + // (absolute value indicates forward / backward) + abs_d = abs(movement_direction); + if (abs_d < 3.0f / 8.0f * M_PI) + keypress_bits |= (u32)1; // Forward + if (abs_d > 5.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 1; // Backward + + // rotate entire coordinate system by 90 degree + abs_d = movement_direction + M_PI_2; + if (abs_d >= M_PI) + abs_d -= 2 * M_PI; + abs_d = abs(abs_d); + // (value now indicates left / right) + if (abs_d < 3.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 2; // Left + if (abs_d > 5.0f / 8.0f * M_PI) + keypress_bits |= (u32)1 << 3; // Right + } + + return keypress_bits; +} - /* - 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); - } - }*/ - } - } +#endif - /* - Calculate player collision box (new and old) - */ - core::aabbox3d 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 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. - */ - touching_ground = false; - - /*std::cout<<"Checking collisions for (" - < (" - <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 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 - - /* - Check the nodes under the player to see from which node the - player is sneaking from, if any. - */ - { - v3s16 pos_i_bottom = floatToInt(position - v3f(0,BS/2,0), BS); - v2f player_p2df(position.X, position.Z); - f32 min_distance_f = 100000.0*BS; - // If already seeking from some node, compare to it. - /*if(m_sneak_node_exists) - { - v3f sneaknode_pf = intToFloat(m_sneak_node, BS); - v2f sneaknode_p2df(sneaknode_pf.X, sneaknode_pf.Z); - f32 d_horiz_f = player_p2df.getDistanceFrom(sneaknode_p2df); - f32 d_vert_f = fabs(sneaknode_pf.Y + BS*0.5 - position.Y); - // Ignore if player is not on the same level (likely dropped) - if(d_vert_f < 0.15*BS) - min_distance_f = d_horiz_f; - }*/ - v3s16 new_sneak_node = m_sneak_node; - for(s16 x=-1; x<=1; x++) - for(s16 z=-1; z<=1; z++) - { - v3s16 p = pos_i_bottom + v3s16(x,0,z); - v3f pf = intToFloat(p, BS); - v2f node_p2df(pf.X, pf.Z); - f32 distance_f = player_p2df.getDistanceFrom(node_p2df); - f32 max_axis_distance_f = MYMAX( - fabs(player_p2df.X-node_p2df.X), - fabs(player_p2df.Y-node_p2df.Y)); - - if(distance_f > min_distance_f || - max_axis_distance_f > 0.5*BS + sneak_max + 0.1*BS) - continue; - - try{ - // The node to be sneaked on has to be walkable - if(nodemgr->get(map.getNode(p)).walkable == false) - continue; - // And the node above it has to be nonwalkable - if(nodemgr->get(map.getNode(p+v3s16(0,1,0))).walkable == true) - continue; - } - catch(InvalidPositionException &e) - { - continue; - } - - min_distance_f = distance_f; - new_sneak_node = p; - } - - bool sneak_node_found = (min_distance_f < 100000.0*BS*0.9); - - if(control.sneak && m_sneak_node_exists) - { - if(sneak_node_found) - m_sneak_node = new_sneak_node; - } - else - { - m_sneak_node = new_sneak_node; - m_sneak_node_exists = sneak_node_found; - } - - /* - If sneaking, the player's collision box can be in air, so - this has to be set explicitly - */ - if(sneak_node_found && control.sneak) - touching_ground = true; - } - - /* - Set new position - */ - setPosition(position); - - /* - Report collisions - */ - if(collision_info) - { - // Report fall collision - if(old_speed.Y < m_speed.Y - 0.1 && !standing_on_unloaded) - { - CollisionInfo info; - info.t = COLLISION_FALL; - info.speed = m_speed.Y - old_speed.Y; - collision_info->push_back(info); - } - } +void PlayerControl::unpackKeysPressed(u32 keypress_bits) +{ + direction_keys = keypress_bits & 0xf; + jump = keypress_bits & (1 << 4); + aux1 = keypress_bits & (1 << 5); + sneak = keypress_bits & (1 << 6); + dig = keypress_bits & (1 << 7); + place = keypress_bits & (1 << 8); + zoom = keypress_bits & (1 << 9); } -void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d) +void PlayerSettings::readGlobalSettings() { - move(dtime, map, pos_max_d, NULL); + free_move = g_settings->getBool("free_move"); + pitch_move = g_settings->getBool("pitch_move"); + fast_move = g_settings->getBool("fast_move"); + continuous_forward = g_settings->getBool("continuous_forward"); + always_fly_fast = g_settings->getBool("always_fly_fast"); + aux1_descends = g_settings->getBool("aux1_descends"); + noclip = g_settings->getBool("noclip"); + autojump = g_settings->getBool("autojump"); } -void LocalPlayer::applyControl(float dtime) +void Player::settingsChangedCallback(const std::string &name, void *data) { - // Clear stuff - swimming_up = false; - - // Random constants - f32 walk_acceleration = 4.0 * BS; - f32 walkspeed_max = 4.0 * BS; - - setPitch(control.pitch); - setYaw(control.yaw); - - v3f move_direction = v3f(0,0,1); - move_direction.rotateXZBy(getYaw()); - - v3f speed = v3f(0,0,0); - - bool free_move = g_settings->getBool("free_move"); - bool fast_move = g_settings->getBool("fast_move"); - bool continuous_forward = g_settings->getBool("continuous_forward"); - - if(free_move || is_climbing) - { - v3f speed = getSpeed(); - speed.Y = 0; - setSpeed(speed); - } - - // Whether superspeed mode is used or not - bool superspeed = false; - - // If free movement and fast movement, always move fast - if(free_move && fast_move) - superspeed = true; - - // Auxiliary button 1 (E) - if(control.aux1) - { - if(free_move) - { - // In free movement mode, aux1 descends - v3f speed = getSpeed(); - if(fast_move) - speed.Y = -20*BS; - else - speed.Y = -walkspeed_max; - setSpeed(speed); - } - else if(is_climbing) - { - v3f speed = getSpeed(); - speed.Y = -3*BS; - setSpeed(speed); - } - else - { - // If not free movement but fast is allowed, aux1 is - // "Turbo button" - if(fast_move) - superspeed = true; - } - } - - if(continuous_forward) - speed += move_direction; - - if(control.up) - { - if(continuous_forward) - superspeed = true; - else - speed += move_direction; - } - if(control.down) - { - speed -= move_direction; - } - if(control.left) - { - speed += move_direction.crossProduct(v3f(0,1,0)); - } - if(control.right) - { - speed += move_direction.crossProduct(v3f(0,-1,0)); - } - if(control.jump) - { - if(free_move) - { - v3f speed = getSpeed(); - if(fast_move) - speed.Y = 20*BS; - else - speed.Y = walkspeed_max; - setSpeed(speed); - } - else if(touching_ground) - { - /* - NOTE: The d value in move() affects jump height by - raising the height at which the jump speed is kept - at its starting value - */ - v3f speed = getSpeed(); - if(speed.Y >= -0.5*BS) - { - speed.Y = 6.5*BS; - setSpeed(speed); - } - } - // Use the oscillating value for getting out of water - // (so that the player doesn't fly on the surface) - else if(in_water) - { - v3f speed = getSpeed(); - speed.Y = 1.5*BS; - setSpeed(speed); - swimming_up = true; - } - else if(is_climbing) - { - v3f speed = getSpeed(); - speed.Y = 3*BS; - setSpeed(speed); - } - } - - // The speed of the player (Y is ignored) - if(superspeed) - speed = speed.normalize() * walkspeed_max * 5.0; - else if(control.sneak) - speed = speed.normalize() * walkspeed_max / 3.0; - else - speed = speed.normalize() * walkspeed_max; - - f32 inc = walk_acceleration * BS * dtime; - - // Faster acceleration if fast and free movement - if(free_move && fast_move) - inc = walk_acceleration * BS * dtime * 10; - - // Accelerate to target speed with maximum increment - accelerate(speed, inc); + ((PlayerSettings *)data)->readGlobalSettings(); } -#endif -